我们可以在 php 的 foreach 循环中使用 IterateAggregate 或 Iterator 吗?
Can we use IterateAggregate or Iterator in foreach loop in php?
我是 php 的初学者,正在从 php.net 学习它。该页面 (http://php.net/manual/en/class.traversable.php) 上的 注释 说:
实现此接口的内部(内置)classes 可以在 foreach 构造中使用,不需要实现 IteratorAggregate 或 Iterator。
这个注释说的是什么?这是否意味着我们可以在 foreach 循环中使用 IteratorAggregate 或 Iterator 而无需任何 class 或者我错了。谁能告诉我这个 note 说的是什么??
IteratorAggregate
是一个 接口,用于创建一个外部迭代器,它允许您遍历自定义 class 对象 使用 foreach
:
class FooBarClass implements IteratorAggregate
{
public $property = "Nothing to see";
public function __construct()
{
}
public function getIterator()
{
return new ArrayIterator($this);
}
}
$obj = new FooBar;
foreach($obj as $key => $value) {
print(var_dump($key, $value) . "\n");
}
Iterator
也是一个 外部迭代器的接口 但允许您的 class 对象或对象在内部迭代它们自己:
class myIterator implements Iterator
{
private $position = 0;
private $array = array('one', 'two', 'three');
function rewind()
{
$this->position = 0;
}
function current()
{
return $this->array[$this->position];
}
function key()
{
return $this->position;
}
function next()
{
++$this->position;
}
function valid()
{
return isset($this->array[$this->position]);
}
}
尽管如此,您仍然可以像 IteratorAggregate
一样遍历对象。
两者的区别在于 IteratorAggregate
比迭代器更容易实现,而且通常速度更快。缺点是它只是用于遍历,并没有提供next()、key()等方法,因为这些方法在foreach遍历时不会被调用。
虽然 Iterator
(或更具体的 OuterIterator or (easier) an IteratorIterator)允许您更好地控制对象的迭代并在 next()、key() 或prev() 失败、缓存() 等
你所指的注释是指PHP的某些内部classes(用C代码编写)可能直接实现了这个接口.任何需要实现 Traversable 的用户空间 class 必须通过实现 IteratorAggregate 或 Iterator 或另一个 Traversable 的后代来实现。参见 Pro PHP by Kevin McArthur 第143f.
Traversable 接口本身是一个抽象基接口(没有接口概要中显示的方法),无法实例化。但是,它可以用来检查 class 是否可以使用 foreach 遍历。
Traversable {
}
混淆部分是对象和数组不实现"Traversable",但can be traversed by foreach, but you cannot check for foreach compatibility using an instanceof
check or type hint。
$myarray = array('one', 'two', 'three');
$myobj = (object)$myarray;
if ( !($myarray instanceof \Traversable) ) {
print "myarray is NOT Traversable";
}
if ( !($myobj instanceof \Traversable) ) {
print "myobj is NOT Traversable";
}
如前所述,每个对象都可以用 foreach 遍历,但是你只能访问 public 属性。引用 Object Iteration 上的 PHP 手册:
PHP 5 provides a way for objects to be defined so it is possible to
iterate through a list of items, with, for example a foreach
statement. By default, all visible properties will be used for the
iteration.
因此,如果您使用私有值和受保护值封装对象并编写 getter 和 setter 方法来访问它,您可能希望 class 实现 IteratorAggregate 或 Iterator 并且编写逻辑,使这些值可以根据需要在 foreach 循环中访问。
简而言之,实现 Traversable 接口的对象(通过 Iterator 或 IteratorAggregate)"act like an array"。但是,没有必要迭代对象。但是如果你想改变它们的行为,你需要实现迭代器。同样的逻辑适用于内置 classes.
我是 php 的初学者,正在从 php.net 学习它。该页面 (http://php.net/manual/en/class.traversable.php) 上的 注释 说:
实现此接口的内部(内置)classes 可以在 foreach 构造中使用,不需要实现 IteratorAggregate 或 Iterator。
这个注释说的是什么?这是否意味着我们可以在 foreach 循环中使用 IteratorAggregate 或 Iterator 而无需任何 class 或者我错了。谁能告诉我这个 note 说的是什么??
IteratorAggregate
是一个 接口,用于创建一个外部迭代器,它允许您遍历自定义 class 对象 使用 foreach
:
class FooBarClass implements IteratorAggregate
{
public $property = "Nothing to see";
public function __construct()
{
}
public function getIterator()
{
return new ArrayIterator($this);
}
}
$obj = new FooBar;
foreach($obj as $key => $value) {
print(var_dump($key, $value) . "\n");
}
Iterator
也是一个 外部迭代器的接口 但允许您的 class 对象或对象在内部迭代它们自己:
class myIterator implements Iterator
{
private $position = 0;
private $array = array('one', 'two', 'three');
function rewind()
{
$this->position = 0;
}
function current()
{
return $this->array[$this->position];
}
function key()
{
return $this->position;
}
function next()
{
++$this->position;
}
function valid()
{
return isset($this->array[$this->position]);
}
}
尽管如此,您仍然可以像 IteratorAggregate
一样遍历对象。
两者的区别在于 IteratorAggregate
比迭代器更容易实现,而且通常速度更快。缺点是它只是用于遍历,并没有提供next()、key()等方法,因为这些方法在foreach遍历时不会被调用。
虽然 Iterator
(或更具体的 OuterIterator or (easier) an IteratorIterator)允许您更好地控制对象的迭代并在 next()、key() 或prev() 失败、缓存() 等
你所指的注释是指PHP的某些内部classes(用C代码编写)可能直接实现了这个接口.任何需要实现 Traversable 的用户空间 class 必须通过实现 IteratorAggregate 或 Iterator 或另一个 Traversable 的后代来实现。参见 Pro PHP by Kevin McArthur 第143f.
Traversable 接口本身是一个抽象基接口(没有接口概要中显示的方法),无法实例化。但是,它可以用来检查 class 是否可以使用 foreach 遍历。
Traversable {
}
混淆部分是对象和数组不实现"Traversable",但can be traversed by foreach, but you cannot check for foreach compatibility using an instanceof
check or type hint。
$myarray = array('one', 'two', 'three');
$myobj = (object)$myarray;
if ( !($myarray instanceof \Traversable) ) {
print "myarray is NOT Traversable";
}
if ( !($myobj instanceof \Traversable) ) {
print "myobj is NOT Traversable";
}
如前所述,每个对象都可以用 foreach 遍历,但是你只能访问 public 属性。引用 Object Iteration 上的 PHP 手册:
PHP 5 provides a way for objects to be defined so it is possible to iterate through a list of items, with, for example a foreach statement. By default, all visible properties will be used for the iteration.
因此,如果您使用私有值和受保护值封装对象并编写 getter 和 setter 方法来访问它,您可能希望 class 实现 IteratorAggregate 或 Iterator 并且编写逻辑,使这些值可以根据需要在 foreach 循环中访问。
简而言之,实现 Traversable 接口的对象(通过 Iterator 或 IteratorAggregate)"act like an array"。但是,没有必要迭代对象。但是如果你想改变它们的行为,你需要实现迭代器。同样的逻辑适用于内置 classes.