Die Antwort lautet „Ja“, aber es gibt eine Bedingung: Durch das Durchlaufen eines Objekts können nur seine öffentlichen Eigenschaften abgerufen werden.
// 普通遍历 class A { public $a1 = '1'; public $a2 = '2'; public $a3 = '3'; private $a4 = '4'; protected $a5 = '5'; public $a6 = '6'; public function test() { echo 'test'; } } $a = new A(); foreach ($a as $k => $v) { echo $k, '===', $v, PHP_EOL; } // a1===1 // a2===2 // a3===3 // a6===6
Egal ob es sich um eine Methode oder eine geschützte oder private Variable handelt, sie kann nicht durchlaufen werden. Es können nur öffentliche Attribute durchlaufen werden. Tatsächlich wird das „Iterator-Muster“, über das wir zuvor gesprochen haben, speziell für die Objektdurchquerung verwendet, und PHP hat die relevanten Schnittstellen für uns vorbereitet. Wir müssen diese Schnittstelle nur implementieren, um den Iterator zu vervollständigen. Das Muster wird erstellt . Spezifische Inhalte finden Sie in der vorherigen Artikelreihe zu Designmustern: PHP Design Patterns Iterator Pattern (empfohlen: „PHP Video Tutorial“)// 实现迭代器接口
class B implements Iterator
{
private $var = [];
public function __construct($array)
{
if (is_array($array)) {
$this->var = $array;
}
}
public function rewind()
{
echo "rewinding\n";
reset($this->var);
}
public function current()
{
$var = current($this->var);
echo "current: $var\n";
return $var;
}
public function key()
{
$var = key($this->var);
echo "key: $var\n";
return $var;
}
public function next()
{
$var = next($this->var);
echo "next: $var\n";
return $var;
}
public function valid()
{
$var = $this->current() !== false;
echo "valid: {$var}\n";
return $var;
}
}
$b = new B([1, 2, 3, 4]);
foreach ($b as $k => $v) {
echo $k, '===', $v, PHP_EOL;
}
// rewinding
// current: 1
// valid: 1
// current: 1
// key: 0
// 0===1
// next: 2
// current: 2
// valid: 1
// current: 2
// key: 1
// 1===2
// next: 3
// current: 3
// valid: 1
// current: 3
// key: 2
// 2===3
// next: 4
// current: 4
// valid: 1
// current: 4
// key: 3
// 3===4
// next:
// current:
// valid:
// 让类可以像数组一样操作 class C implements ArrayAccess, IteratorAggregate { private $container = []; public function __construct() { $this->container = [ "one" => 1, "two" => 2, "three" => 3, ]; } public function offsetSet($offset, $value) { if (is_null($offset)) { $this->container[] = $value; } else { $this->container[$offset] = $value; } } public function offsetExists($offset) { return isset($this->container[$offset]); } public function offsetUnset($offset) { unset($this->container[$offset]); } public function offsetGet($offset) { return isset($this->container[$offset]) ? $this->container[$offset] : null; } public function getIterator() { return new B($this->container); } } $c = new C(); var_dump($c); $c['four'] = 4; var_dump($c); $c[] = 5; $c[] = 6; var_dump($c); foreach($c as $k=>$v){ echo $k, '===', $v, PHP_EOL; } // rewinding // current: 1 // valid: 1 // current: 1 // key: one // one===1 // next: 2 // current: 2 // valid: 1 // current: 2 // key: two // two===2 // next: 3 // current: 3 // valid: 1 // current: 3 // key: three // three===3 // next: 4 // current: 4 // valid: 1 // current: 4 // key: four // four===4 // next: 5 // current: 5 // valid: 1 // current: 5 // key: 0 // 0===5 // next: 6 // current: 6 // valid: 1 // current: 6 // key: 1 // 1===6 // next: // current: // valid:
Diese Schnittstelle erfordert die Implementierung von vier Methoden:
offsetSet($offset, $value), legt den Wert basierend auf dem Offset fest- offsetExists($offset) und bestimmt, ob Inhalt basierend auf dem Offset vorhanden ist
- offsetUnset(( $offset), lösche den Inhalt basierend auf dem Offset
- offsetGet($offset), erhalte den Inhalt basierend auf dem Offset
- Der Offset wird hier oft als Index bezeichnet. Durch die Implementierung dieser vier Methoden können wir Objekte wie Arrays bedienen. Natürlich nutzen wir in der täglichen Entwicklung die Möglichkeit, diese Objekte, einschließlich Iteratoren, zu durchlaufen, möglicherweise nicht sehr oft. Normalerweise konvertieren wir das Objekt im nächsten Schritt direkt in ein Array (Array) obj. In Java, insbesondere in JavaBean, gibt es jedoch häufig eine List
innerhalb der Klasse als eigenes Objekt, um ihren eigenen Sammlungsstatus darzustellen. Durch einen Vergleich haben wir herausgefunden, dass PHP solche Funktionen vollständig implementieren kann und es bequemer ist, Iteratoren und die ArrayAccess-Schnittstelle zu verwenden, um ähnliche Funktionen zu erreichen. Dies ist eine sehr nützliche Wissenserweiterung. Vielleicht können Sie diese Fähigkeiten in Ihrem nächsten Projekt nutzen!
测试代码: https://github.com/zhangyue0503/dev-blog/blob/master/php/201912/source/PHP%E6%80%8E%E4%B9%88%E9%81%8D%E5%8E%86%E5%AF%B9%E8%B1%A1%EF%BC%9F.ph