Before we delve into this design pattern, let’s take a look at an interview question first, from Brother Niao’s blog,
The question is like this:
To enable objects to perform foreach loops like arrays, the required properties must be private.
It is difficult to implement without using the iterator pattern. Let’s look at the implementation code first:
sample.php
<?php class Sample implements Iterator{ private $_arr; public function __construct(Array $arr){ $this->_arr = $arr; } public function current(){ return current($this->_arr); } public function next(){ return next($this->_arr); } public function key(){ return key($this->_arr); } public function valid(){ return $this->current() !== false; } public function rewind(){ reset($this->_arr); } }
<?php require 'Sample.php'; $arr = new Sample(['max', 'ben', 'will']); foreach ($arr as $k=>$v){ echo $k."-".$v."<br />"; }
The Iterator interface comes from the spl class library of PHP. After writing related articles on design patterns, I will further study this class library.
In addition, I found a piece of implementation code about the iterator pattern in the Yii framework on the Internet:
class CMapIterator implements Iterator { /** * @var array the data to be iterated through */ private $_d; /** * @var array list of keys in the map */ private $_keys; /** * @var mixed current key */ private $_key; /** * Constructor. * @param array the data to be iterated through */ public function __construct(&$data) { $this->_d=&$data; $this->_keys=array_keys($data); } /** * Rewinds internal array pointer. * This method is required by the interface Iterator. */ public function rewind() { $this->_key=reset($this->_keys); } /** * Returns the key of the current array element. * This method is required by the interface Iterator. * @return mixed the key of the current array element */ public function key() { return $this->_key; } /** * Returns the current array element. * This method is required by the interface Iterator. * @return mixed the current array element */ public function current() { return $this->_d[$this->_key]; } /** * Moves the internal pointer to the next array element. * This method is required by the interface Iterator. */ public function next() { $this->_key=next($this->_keys); } /** * Returns whether there is an element at current position. * This method is required by the interface Iterator. * @return boolean */ public function valid() { return $this->_key!==false; } } $data = array('s1' => 11, 's2' => 22, 's3' => 33); $it = new CMapIterator($data); foreach ($it as $row) { echo $row, '<br />'; }
The official definition of the iterator design pattern is: use the iterator pattern to provide unified access to aggregate objects, that is, to provide a External iterator to access and traverse the aggregate object without exposing the internal structure of the object. Also called Cursor mode.
Okay, I don’t quite understand. Why do we need to use such an iterator mode to implement it even though arrays can already be traversed using foreach? We can only wait for the deepening of work experience to further understand.
Reference documents:
http://www.cnblogs.com/davidhhuan/p/4248206.html
http://blog.csdn.net/hguisu/article/details/7552841
http:// www.phppan.com/2010/04/php-iterator-and-yii-cmapiterator/
PHP source code reading notes twenty-four: Analysis of the reasons why iteration cannot be completed when the value is false in iterator implementation: http:/ /www.phppan.com/2010/04/php-source-24-iterator-false-value/
The above introduces the introduction to design patterns - iterator pattern (php version), including the relevant content. I hope it will be helpful to friends who are interested in PHP tutorials.