UNPKG

manual-php

Version:
230 lines (196 loc) 4.38 kB
# 遍历对象 PHP 提供了一种定义对象的方法使其可以通过单元列表来遍历,例如用 `foreach` 语句。默认情况下,所有可见属性都将被用于遍历。 ```php <?php class Foo { /** * Public property. * * @var string */ public string $public = 'public'; /** * Protected property. * * @var string */ protected string $protected = 'protected'; /** * Private property. * * @var string */ private string $private = 'private'; /** * Print all visibility properties. * * @param void * @return void */ public function method() { foreach ($this as $key => $value) { var_dump("$key => $value"); } } } $foo = new Foo(); foreach ($foo as $key => $value) { var_dump("$key => $value"); } // string(16) "public => public" $foo->method(); // string(16) "public => public" // string(22) "protected => protected" // string(18) "private => private" ``` 更进一步,可以实现 `Iterator` 接口。可以让对象自行决定如何遍历以及每次遍历时那些值可用。 ```php <?php class Foo implements Iterator { /** * Store an array. * * @var array */ private array $property; /** * Store an array to the property. * * @param array $array * @return void */ public function __construct(array $array) { $this->property = $array; } /** * Return the current element of the specified property. * * @param void * @return int */ public function current(): int { var_dump(__METHOD__); return current($this->property); } /** * Advance the internal pointer of the specified property. * * @param void * @return void */ public function next() { var_dump(__METHOD__); next($this->property); } /** * Return the current key of the specified property. * * @param void * @return int */ public function key(): int { var_dump(__METHOD__); return key($this->property); } /** * Return the validity of the current position of the specified property. * * @param void * @return bool */ public function valid(): bool { var_dump(__METHOD__); return current($this->property) !== false; } /** * Set the internal pointer of the specified property to the first element. * * @param void * @return void */ public function rewind() { var_dump(__METHOD__); reset($this->property); } } $foo = new Foo([2, 4, 5]); foreach ($foo as $key => $value) { var_dump("$key => $value"); echo "\r\n"; } // string(11) "Foo::rewind" // string(10) "Foo::valid" // string(12) "Foo::current" // string(8) "Foo::key" // string(6) "0 => 2" // string(9) "Foo::next" // string(10) "Foo::valid" // string(12) "Foo::current" // string(8) "Foo::key" // string(6) "1 => 4" // string(9) "Foo::next" // string(10) "Foo::valid" // string(12) "Foo::current" // string(8) "Foo::key" // string(6) "2 => 5" // string(9) "Foo::next" // string(10) "Foo::valid" ``` 可以用 `IteratorAggregate` 接口以替代实现所有的 `Iterator` 方法。 `IteratorAggregate` 只需要实现一个方法 `getIterator()` ,其应返回一个实现了 `Iterator` 的类的实例。 ```php <?php class Foo implements IteratorAggregate { /** * Just a test property. * * @var string */ public string $foo = 'foo'; /** * Just a test property. * * @var string */ public string $bar = 'bar'; /** * Just a test property. * * @var string */ public string $baz = 'baz'; /** * Just a test property. * * @var string */ public string $qux = 'qux'; /** * Return an external iterator. * * @param void * @return ArrayIterator */ public function getIterator(): ArrayIterator { return new ArrayIterator($this); } } $foo = new Foo(); foreach ($foo as $key => $value) { var_dump("$key => $value"); } // string(10) "foo => foo" // string(10) "bar => bar" // string(10) "baz => baz" // string(10) "qux => qux" ```