Iterator 接口


首先要從foreach說起,我們都知道對象,數組和對象可以被foreach語法遍歷,數字和字符串卻不行。
其實除了數組和對象之外PHP內部還提供了一個 Iterator 接口,實現了Iterator接口的對象,也是可以被foreach語句遍歷,當然跟普通對象的遍歷就很不一樣了。 以下面的代碼為例:
class Number implements Iterator{   protected $key;   protected $val;   protected $count;   public function __construct(int $count){     $this->count = $count;   }   public function rewind(){     $this->key = 0;     $this->val = 0;   }   public function next(){   $this->key += 1;   $this->val += 2;   }   public function current(){     return $this->val;   }   public function key(){   return $this->key + 1;   }   public function valid(){     return $this->key < $this->count;   } } foreach (new Number(5) as $key => $value){   echo "{$key} - {$value}\n"; } 

這個例子將輸出

1 - 0
2 - 2
3 - 4
4 - 6
5 - 8

關於上面的number對象,被遍歷的過程。如果是初學者,可能會出現有點懵的情況。為了深入的了解Number對象被遍歷的時候內部是怎么工作的,我將代碼改了一下,將接口內的每個方法都盡心輸出,借此來窺探一下遍歷時對象內部方法的的執行情況。

 

class Number implements Iterator{ protected $i = 1; protected $key; protected $val; protected $count; public function __construct(int $count){ $this->count = $count; echo "第{$this->i}步:對象初始化.\n"; $this->i++; } public function rewind(){ $this->key = 0; $this->val = 0; echo "第{$this->i}步:rewind()被調用.\n"; $this->i++; } public function next(){ $this->key += 1; $this->val += 2; echo "第{$this->i}步:next()被調用.\n"; $this->i++; } public function current(){ echo "第{$this->i}步:current()被調用.\n"; $this->i++; return $this->val; } public function key(){ echo "第{$this->i}步:key()被調用.\n"; $this->i++; return $this->key; } public function valid(){ echo "第{$this->i}步:valid()被調用.\n"; $this->i++; return $this->key < $this->count; } } $number = new Number(5); echo "start...\n"; foreach ($number as $key => $value){ echo "{$key} - {$value}\n"; } echo "...end...\n";

 

以上代碼輸出如下

 

第1步:對象初始化. start... 第2步:rewind()被調用. 第3步:valid()被調用. 第4步:current()被調用. 第5步:key()被調用.
0 - 0 第6步:next()被調用. 第7步:valid()被調用. 第8步:current()被調用. 第9步:key()被調用.
1 - 2 第10步:next()被調用. 第11步:valid()被調用. 第12步:current()被調用. 第13步:key()被調用.
2 - 4 第14步:next()被調用. 第15步:valid()被調用. 第16步:current()被調用. 第17步:key()被調用.
3 - 6 第18步:next()被調用. 第19步:valid()被調用. 第20步:current()被調用. 第21步:key()被調用.
4 - 8 第22步:next()被調用. 第23步:valid()被調用.
...end...

 

看到這里,我相信大家對Iterator接口已經有一定認識了。

會發現當對象被foreach的時候,內部的valid,current,key方法會依次被調用,其返回值便是foreach語句的key和value。

循環的終止條件則根據valid方法的返回而定。

如果返回的是true則繼續循環,如果是false則終止整個循環,結束遍歷。

當一次循環體結束之后,將調用next進行下一次的循環直到valid返回false。

而rewind方法則是在整個循環開始前被調用,這樣保證了我們多次遍歷得到的結果都是一致的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM