迭代器有時又稱游標(cursor)是程式設計的軟體設計模式,可在容器物件(container,例如list或vector)上遍訪的介面,設計人員無需關心容器物件的內容。
各種語言實作Iterator的方式皆不盡同,有些物件導向語言像Java, C#, Python, Delphi都已將Iterator的特性內建語言當中,完美的跟語言整合,我們稱之隱式迭代器(implicit iterator),但像是C++語言本身就沒有Iterator的特色,但STL仍利用template實作了功能強大的iterator。
PHP5開始支援了介面, 並且內建了Iterator介面, 所以如果你定義了一個類,並實現了Iterator介面,那麼你的這個類對象就是ZEND_ITER_OBJECT,否則就是ZEND_ITER_PLAIN_OBJECT.
對於ZEND_ITER_PLAIN_OBJECT的類,foreach會通過HASH_OF擷取該對象的預設屬性數組,然後對該數組進行foreach.
而對於ZEND_ITER_OBJECT的類對象,則會通過調用對象實現的Iterator介面相關函數來進行foreach。
06 |
class sample
implements Iterator { |
09 |
public
function __construct(&$data) { |
12 |
public
function current() { |
13 |
return
current($this->_items); |
16 |
public
function next() { |
20 |
public
function key() { |
21 |
return
key($this->_items); |
24 |
public
function rewind() { |
28 |
public
function valid() {
|
29 |
return
($this->current() !== FALSE); |
34 |
$data =
array(1, 2, 3, 4, 5); |
35 |
$sa =
new sample($data); |
36 |
foreach ($sa
AS $key => $row) { |
37 |
echo
$key, ' ',
$row, '<br />'; |
舉幾個迭代器的使用範圍:
- 使用返回迭代器的包或庫時(如PHP5中的SPL迭代器)
- 無法在一次的調用擷取容器的所有元素時
- 要處理數量巨大的無素時(資料庫中的表以GB計的資料)
- ……
不同的迭代器有不同的介面,例如PHP SPL迭代器中包括Next()(移動到下一個元素),corrent()(返回當前元素),valid()(檢查迭代結尾),rewind()(從頭重新開始),key()(返回當前元素的索引)。當然你可以自己寫適合自己用的迭代器,也可以用系統中的迭代器。
一般是使用foreach來使用迭代器,下面整理了一下代碼:
02 |
class sample
implements Iterator |
04 |
private
$_items = array(1,2,3,4,5,6,7); |
06 |
public
function __construct() { |
09 |
public
function rewind() { reset($this->_items); } |
10 |
public
function current() { return
current($this->_items); } |
11 |
public
function key() { return
key($this->_items); } |
12 |
public
function next() { return
next($this->_items); } |
13 |
public
function valid() { return
( $this->current() !== false ); } |
17 |
foreach($sa
as $key => $val){ |
18 |
print
$key . "=>"
.$val; |
while迴圈也可以:
2 |
while ($itertor->valid()){//判斷是不是最後元素 |
3 |
$element=$itertor->current();//擷取當前元素 |
4 |
$itertor->next();//移動到下一個元素 |
為什麼要學習PHP的迭代器呢?有個很重要的原因:利用PHP的迭代器可以利用物件導向實現常見的資料結構,例如列表,堆棧,隊列與圖。後面會做一個專題,用PHP實現大部分的資料結構,而且以物件導向的形式。所以這裡先預熱了一下PHP的迭代器。