我们可以在php的foreach循环中使用IterateAggregate或Iterator吗?

5 php foreach traversable

我是php的初学者,从php.net学习它.该页面上的注释(http://php.net/manual/en/class.traversable.php)表示:

实现此接口的内部(内置)类可以在foreach构造中使用,而不需要实现IteratorAggregate或Iterator.

这个说明是什么意思?这是否意味着我们可以在没有任何类的情况下在foreach循环中使用IteratorAggregateIterator,或者可能是我错了.任何人都能说出这个音符说的是什么?

wp7*_*8de 2

IteratorAggregate是一个创建外部迭代器的接口,它允许您使用以下方式遍历自定义类对象foreach

\n\n\n\n
class FooBarClass implements IteratorAggregate\n{\n    public $property = "Nothing to see";\n\n    public function __construct()\n    {\n    }\n\n    public function getIterator()\n    {\n        return new ArrayIterator($this);\n    }\n}\n\n$obj = new FooBar;\n\nforeach($obj as $key => $value) {\n    print(var_dump($key, $value) . "\\n");\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

Iterator 也是外部迭代器的接口,但允许您的类或对象在内部迭代自身:

\n\n
class myIterator implements Iterator\n{\n    private $position = 0;\n    private $array = array(\'one\', \'two\', \'three\');\n\n    function rewind()\n    {\n        $this->position = 0;\n    }\n\n    function current()\n    {\n        return $this->array[$this->position];\n    }\n\n    function key()\n    {\n        return $this->position;\n    }\n\n    function next()\n    {\n        ++$this->position;\n    }\n\n    function valid()\n    {\n        return isset($this->array[$this->position]);\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

尽管如此,您仍然可以以与 相同的方式遍历对象 IteratorAggregate

\n\n

两者之间的区别在于,它IteratorAggregate比 Iterator 更容易实现,而且通常速度更快。缺点是它仅用于遍历,不提供 next()、key() 等方法,因为这些方法在 foreach 遍历期间不会被调用。

\n\n

虽然Iterator(或更具体的OuterIterator或(更简单的)IteratorIterator)允许您对对象的迭代进行更精细的控制,并在 next()、key() 或 prev() 失败时添加自定义异常,但 caching() , ETC。

\n\n

您所指的注释意味着 PHP 的某些内部类(用 C 代码编写)可以直接实现此接口。任何需要实现 Traversable 的用户态类都必须通过实现 IteratorAggregate 或 Iterator 或 Traversable 的另一个后代来实现。请参阅Kevin McArthur 的《Pro PHP》第 14 页。143f。

\n\n

Traversable 接口本身是一个抽象基接口(没有接口概要中所示的方法),无法实例化。然而,它可以用来检查一个类是否可以使用 foreach 进行遍历。

\n\n
Traversable {\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

令人困惑的部分是对象和数组没有实现“可遍历”,但可以通过 foreach遍历,但不能instanceof使用检查或类型提示来检查 foreach 兼容性。

\n\n
$myarray = array(\'one\', \'two\', \'three\');\n$myobj = (object)$myarray;\n\nif ( !($myarray instanceof \\Traversable) ) {\n\xc2\xa0 \xc2\xa0 print "myarray is NOT Traversable";\n}\nif ( !($myobj instanceof \\Traversable) ) {\n\xc2\xa0 \xc2\xa0 print "myobj is NOT Traversable";\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

正如前面提到的,每个对象都可以用 foreach 遍历,但随后你只能访问公共属性。引用 PHP 手册中关于对象迭代的内容:

\n\n
\n

PHP 5 提供了一种定义对象的方法,因此可以使用例如 foreach 语句来迭代项目列表。默认情况下,所有可见属性都将用于\n 迭代。

\n
\n\n

因此,如果您用私有和受保护的值封装一个对象,并编写 getter 和 setter 方法来访问它,您可能希望您的类实现 IteratorAggregate 或 Iterator,并编写逻辑以使这些值根据需要在 foreach 循环中可访问。

\n\n

简而言之,实现 Traversable 接口(通过 Iterator 或 IteratorAggregate)的对象“就像一个数组”。但是,迭代对象并不是必需的。但如果你想改变它们的行为,你需要实现 Iterator。相同的逻辑适用于内置类。

\n