답은 '예'입니다. 하지만 조건이 있습니다. 즉, 객체를 순회하면 해당 객체의 공용 속성만 얻을 수 있습니다.
// 普通遍历 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
메서드든, 보호 변수든, 개인 변수든 상관없이 순회할 수 없습니다. 공용 속성만 탐색할 수 있습니다. 사실 앞서 디자인 패턴에 대해 이야기할 때 이야기한 Iterator 패턴은 특별히 객체 탐색에 사용되며, PHP는 우리를 위해 관련 인터페이스를 준비했습니다. 이 인터페이스만 구현하면 반복자가 패턴이 생성됩니다. . 구체적인 내용은 디자인 패턴에 대한 이전 기사 시리즈를 참조하세요. PHP 디자인 패턴 반복자 패턴(권장: "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:
오늘의 기사가 이전에 언급한 반복자 패턴에 대해서만 이야기한다면 다음과 같습니다. 너무 지루해서 좀 더 흥미로운 응용 방법을 배워야 합니다. 즉, 객체를 배열처럼 조작할 수 있습니다. 이는 실제로 PHP가 이미 준비한 인터페이스인 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:
이 인터페이스에는
- offsetSet($offset, $value), 오프셋을 기준으로 값 설정
- offsetExists($offset), 오프셋을 기준으로 콘텐츠가 있는지 확인하는 네 가지 메서드를 구현해야 합니다
- offsetUnset(( $offset), 오프셋을 기준으로 콘텐츠 삭제
- offsetGet($offset), 오프셋을 기준으로 콘텐츠 가져오기
여기서 오프셋은 우리가 종종 첨자라고 부르는 것입니다. 이 네 가지 메소드를 구현함으로써 객체를 배열처럼 조작할 수 있습니다. 물론 일상적인 개발에서는 반복자를 포함하여 이러한 객체를 탐색하는 기능을 자주 사용하지 않을 수도 있습니다. 일반적으로 다음 단계를 위해 객체를 배열(array) obj로 직접 변환합니다. 그러나 Java, 특히 JavaBean에서는 자체 컬렉션 상태를 나타내는 자체 개체로 클래스 내부에 List