【PHP】對象遍曆

來源:互聯網
上載者:User

我們知道,php中,foreach可以很方便地對可迭代結構(例如數組,再如對象)進行迭代操作:

foreach( $array as $elem){var_dump($elem);}
foreach($obj as $key=>$value){echo "$key=>$value".PHP_EOL;}

因而我們想:如果對於一個執行個體化對象,對其進行foreach操作,會發生什麼事情呢?

首先我們定義的基礎類為:

Class Test{/* one public variable */public $a;public $b;/* one private variable */private $c;public function __construct(){$this->a = "public";$this->b = "public";$this->c = "private";}public function traverseInside(){foreach($this as $key=>$value){echo $key."=>".$value.EOL;}}}

然後我們執行個體化該類,對其進行迭代,並與內部迭代的結果進行比較:

$test = new Test;echo "<hr>";echo "traverse outside:".EOL;foreach( $test as $key=>$value ){echo $key."=>".$value.EOL;}echo "<hr>";echo "traverse inside:".EOL;$test->traverseInside();

迭代的結果為:

可以看出:外部foreach迴圈的結果,只是將對象的公有屬性(public)迴圈出來了,而對於私人屬性(private),外部foreach是無法迴圈出來的。因而我們如果想要在外部通過foreach迴圈出類的所有的屬性(公有的和私人的),僅僅依靠foreach是不行的,必須要對類進行“改造”。如何對類進行改造呢?如果你瞭解foreach的實現(參考laruence的部落格:http://www.laruence.com/2008/11/20/630.html),那麼可以很輕鬆地找到相應的方案。另外一方面,《設計模式-可複用物件導向軟體設計的基礎》中也提到:通過將對象的訪問和遍曆從對象中分離出來並放入一個迭代器對象中,迭代器模式可以實現以不同的方式對對象進行遍曆。我們暫時不去深挖這句話的意思,只要知道,使用迭代器可以對對象進行遍曆即可。

PHP手冊<預定義介面>部分指出:要實現迭代器模式,需要在可迭代對象中實現如下介面:

abstractpublicmixedcurrent( void )abstractpublicscalarkey( void )abstractpublicvoidnext( void )abstractpublicvoidrewind( void )abstractpublicbooleanvalid( void )

有了這個。實現迭代器模式就很方便了,一個簡單的執行個體如下:

class TestIterator implements Iterator {    private $point = 0;    private $data = array(        "one","two","three",    );      public function __construct() {        $this->point = 0;    }    function rewind() {        $this->point = 0;    }    function current() {        return $this->data[$this->point];    }    function key() {        return $this->point;    }    function next() {        ++$this->point;    }    function valid() {        return isset($this->data[$this->point]);    }}$it = new TestIterator;foreach($it as $key => $value) {    echo $key, $value;    echo "\n";}

當然,使用了迭代器的對象可以以如下方式進行遍曆:

$it = new TestIterator;$it->rewind();while ($it->valid()){    $key = $it->key();    $value = $it->current();    echo "$key=>$value";    $it->next();}

最後附上YII中ListIterator(顧名思義,實現對List的迭代操作的迭代器)的實現:

<?php/** * CListIterator class file. * * @author Qiang Xue <qiang.xue@gmail.com> * @link http://www.yiiframework.com/ * @copyright Copyright  2008-2011 Yii Software LLC * @license http://www.yiiframework.com/license/ *//** * CListIterator implements an interator for {@link CList}. * * It allows CList to return a new iterator for traversing the items in the list. * * @author Qiang Xue <qiang.xue@gmail.com> * @version $Id$ * @package system.collections * @since 1.0 */class CListIterator implements Iterator{/** * @var array the data to be iterated through */private $_d;/** * @var integer index of the current item */private $_i;/** * @var integer count of the data items */private $_c;/** * Constructor. * @param array $data the data to be iterated through */public function __construct(&$data){$this->_d=&$data;$this->_i=0;$this->_c=count($this->_d);}/** * Rewinds internal array pointer. * This method is required by the interface Iterator. */public function rewind(){$this->_i=0;}/** * Returns the key of the current array item. * This method is required by the interface Iterator. * @return integer the key of the current array item */public function key(){return $this->_i;}/** * Returns the current array item. * This method is required by the interface Iterator. * @return mixed the current array item */public function current(){return $this->_d[$this->_i];}/** * Moves the internal pointer to the next array item. * This method is required by the interface Iterator. */public function next(){$this->_i++;}/** * Returns whether there is an item at current position. * This method is required by the interface Iterator. * @return boolean */public function valid(){return $this->_i<$this->_c;}}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.