遍历对象
PHP 提供了一种定义对象的方法使其可以通过单元列表来遍历,例如用 foreach
语句。默认情况下,所有可见属性都将被用于遍历。
<?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
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
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"