La réponse est oui, mais il y a une condition, c'est-à-dire que traverser un objet ne peut obtenir que ses propriétés publiques.
// 普通遍历 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
Peu importe qu'il s'agisse d'une méthode ou d'une variable protégée ou privée, elle ne peut pas être parcourue. Seuls les attributs publics peuvent être traversés. En fait, le Modèle d'itérateur dont nous avons parlé précédemment en parlant de modèles de conception est spécifiquement utilisé pour la traversée d'objets, et PHP a préparé les interfaces pertinentes pour nous. Il nous suffit d'implémenter cette interface. le modèle d’itérateur peut être complété. Pour un contenu spécifique, veuillez vous référer à la série précédente d'articles sur les modèles de conception : PHP Design Patterns Iterator Pattern (recommandé : "Tutoriel vidéo PHP")
// 实现迭代器接口 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:
Si l'article d'aujourd'hui ne parle que de quoi J'en ai déjà parlé. Le modèle d'itérateur est trop ennuyeux, nous devons donc apprendre une application plus intéressante. C'est pour permettre aux objets d'être manipulés comme des tableaux. Il s'agit en fait d'utiliser une interface que PHP nous a déjà préparée : ArrayAccess.
// 让类可以像数组一样操作 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:
Cette interface nous demande d'implémenter quatre méthodes :
- offsetSet($offset, $value), définir la valeur en fonction du décalage
- offsetExists($ offset ), déterminer si le contenu existe en fonction du décalage
- offsetUnset($offset), supprimer le contenu en fonction du décalage
- offsetGet($offset), obtenir le contenu en fonction du décalage
Le décalage ici est ce que nous appelons souvent l'indice. En implémentant ces quatre méthodes, nous pouvons faire fonctionner des objets comme des tableaux. Bien sûr, dans le développement quotidien, nous n’utilisons pas très souvent la possibilité de parcourir ces objets, y compris les itérateurs. Habituellement, nous convertirons directement l'objet en un obj tableau (array) pour l'étape suivante. Cependant, en Java, en particulier dans JavaBean, il existe souvent un List8742468051c85b06f0a0af9e3e506b5c à l'intérieur de la classe comme son propre objet pour représenter son propre état de collection. Par comparaison, nous avons constaté que PHP peut pleinement implémenter de telles capacités et qu'il est plus pratique d'utiliser des itérateurs et l'interface ArrayAccess pour obtenir des capacités similaires. Il s’agit d’une extension de connaissances très utile. Peut-être pourrez-vous utiliser ces capacités dans votre prochain projet !
测试代码: 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