我是php的初学者,从php.net学习它.该页面上的注释(http://php.net/manual/en/class.traversable.php)表示:
实现此接口的内部(内置)类可以在foreach构造中使用,而不需要实现IteratorAggregate或Iterator.
这个说明是什么意思?这是否意味着我们可以在没有任何类的情况下在foreach循环中使用IteratorAggregate或Iterator,或者可能是我错了.任何人都能说出这个音符说的是什么?
这IteratorAggregate是一个创建外部迭代器的接口,它允许您使用以下方式遍历自定义类对象foreach:
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}\nRun Code Online (Sandbox Code Playgroud)\n\n这Iterator 也是外部迭代器的接口,但允许您的类或对象在内部迭代自身:
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}\nRun Code Online (Sandbox Code Playgroud)\n\n尽管如此,您仍然可以以与 相同的方式遍历对象 IteratorAggregate。
两者之间的区别在于,它IteratorAggregate比 Iterator 更容易实现,而且通常速度更快。缺点是它仅用于遍历,不提供 next()、key() 等方法,因为这些方法在 foreach 遍历期间不会被调用。
虽然Iterator(或更具体的OuterIterator或(更简单的)IteratorIterator)允许您对对象的迭代进行更精细的控制,并在 next()、key() 或 prev() 失败时添加自定义异常,但 caching() , ETC。
您所指的注释意味着 PHP 的某些内部类(用 C 代码编写)可以直接实现此接口。任何需要实现 Traversable 的用户态类都必须通过实现 IteratorAggregate 或 Iterator 或 Traversable 的另一个后代来实现。请参阅Kevin McArthur 的《Pro PHP》第 14 页。143f。
\n\nTraversable 接口本身是一个抽象基接口(没有接口概要中所示的方法),无法实例化。然而,它可以用来检查一个类是否可以使用 foreach 进行遍历。
\n\nTraversable {\n}\nRun Code Online (Sandbox Code Playgroud)\n\n令人困惑的部分是对象和数组没有实现“可遍历”,但可以通过 foreach遍历,但不能instanceof使用检查或类型提示来检查 foreach 兼容性。
$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}\nRun Code Online (Sandbox Code Playgroud)\n\n正如前面提到的,每个对象都可以用 foreach 遍历,但随后你只能访问公共属性。引用 PHP 手册中关于对象迭代的内容:
\n\n\n\n\nPHP 5 提供了一种定义对象的方法,因此可以使用例如 foreach 语句来迭代项目列表。默认情况下,所有可见属性都将用于\n 迭代。
\n
因此,如果您用私有和受保护的值封装一个对象,并编写 getter 和 setter 方法来访问它,您可能希望您的类实现 IteratorAggregate 或 Iterator,并编写逻辑以使这些值根据需要在 foreach 循环中可访问。
\n\n简而言之,实现 Traversable 接口(通过 Iterator 或 IteratorAggregate)的对象“就像一个数组”。但是,迭代对象并不是必需的。但如果你想改变它们的行为,你需要实现 Iterator。相同的逻辑适用于内置类。
\n