SPL 迭代器
《迭代器設計模式和 PHP》中必須論述“標準 PHP 庫”(SPL)迭代器。雖然,使用 while 循環(huán)結構可以非常緊湊,并且也很有用,但是 PHP 代碼或許更適合數組迭代的 foreach 結構。直接在 foreach 循環(huán)中使用集合合適嗎?這其實就是 SPL 迭代器的目標。(盡管本章整篇都是寫 PHP5,下列 SPL 代碼只能在 PHP5 中運行,并且僅當在 PHP5 編譯中將 SPL 啟用。)
Fuecks 寫過一篇文章,詳細地介紹了 SPL 和 SPL 迭代器;請參閱。使用 SPL 是一種完全不同的實現(xiàn)迭代的方法,因此首先介紹一個新單元測試例子和一個新的類 ForeachableLibrary。
class SplIteratorTestCase extends UnitTestCase { protected $lib; function setup() { $this->lib = new ForeachableLibrary; $this->lib->add(new Media(‘name1’, 2000)); $this->lib->add(new Media(‘name2’, 2002)); $this->lib->add(new Media(‘name3’, 2001)); } function TestForeach() { $output = ‘’; foreach($this->lib as $item) { $output .= $item->name; } $this->assertEqual(‘name1name2name3’, $output); } }
ForeachableLibrary 是實現(xiàn) SPL 迭代器接口的集合。你必須執(zhí)行 5 個函數來創(chuàng)建 SPL 迭代器:current()、next()、key()、valid() 和 rewind()。 key() 返回集合的當前索引。 rewind() 類似于 reset():在集合啟動時重新啟動迭代。
class ForeachableLibrary extends Library implements Iterator { protected $valid; function current() { return current($this->collection); } function next() { $this->valid = (false !== next($this->collection)); } function key() { return key($this->collection); } function valid() { return $this->valid; } function rewind() { $this->valid = (false !== reset($this->collection)); } }
這里,該代碼僅僅實現(xiàn)了處理 $collection 屬性的必需的函數。(如果你沒有實現(xiàn)所有 5 個函數,并且將實現(xiàn)迭代器添加到類 definition,則 PHP 將出現(xiàn)致命錯誤。)測試尚不成熟,因此,什么都有可能發(fā)生。存在一個問題:事實受限于一種迭代類型 - 排序,或者 fil- tering 不可用?梢圆扇〈胧﹣碚{整這種情況?是的!應用從策略模式中學到的知識(請參閱第 7 章),將 SPL 迭代器的 5 個函數作為另一個對象的示例。這是關于 PolymorphicForeachableLibrary 的測試。
class PolySplIteratorTestCase extends UnitTestCase { protected $lib; function setup() { $this->lib = new PolymorphicForeachableLibrary; $this->lib->add(new Media(‘name1’, 2000)); $this->lib->add(new Media(‘name2’, 2002)); $this->lib->add(new Media(‘name3’, 2001)); } function TestForeach() { $output = ‘’; foreach($this->lib as $item) { $output .= $item->name; } $this->assertEqual(‘name1name2name3’, $output); } }
這種情況與 SplIteratorTestCase 測試的唯一差別在于 $this->lib 屬性類是在 setUp() 方法中創(chuàng)建的。這意味著:這兩個類的運行方式必須一致。PolymorphicForeachableLibrary:class PolymorphicForeachableLibrary擴展庫
implements Iterator { protected $iterator; function current() { return $this->iterator->current(); } function next() { return $this->iterator->next(); } function key() { return $this->iterator->key(); } function valid() { return $this->iterator->valid(); } function rewind() { $this->iterator = new StandardLibraryIterator($this->collection); $this->iterator->rewind(); } }
擴展庫加入集合處理方法。并添加 SPL 方法,這些方法代表了 $iterator 屬性,在 rewind() 中創(chuàng)建。以下是StandardLibraryIterator 的代碼。
class StandardLibraryIterator { protected $valid; protected $collection; function __construct($collection) { $this->collection = $collection; } function current() { return current($this->collection); } function next() { $this->valid = (false !== next($this->collection)); } function key() { return key($this->collection); } function valid() { return $this->valid; } function rewind() { $this->valid = (false !== reset($this->collection)); } }
該代碼看起來很熟悉:實際上,這來自于 5 個 SPL 函數ForeachableLibrary 類。
出處:phpchina
責任編輯:bluehearts
上一頁 php設計模式介紹之迭代器模式 [6] 下一頁 php設計模式介紹之迭代器模式 [8]
◎進入論壇網絡編程版塊參加討論
|