說到迭代器這個東西,PHP內置的迭代器還真多。迭代器到底來做什麼的呢,其實就是用來遍歷一個對象內部數據並且獲得想要的結構。迭代器它可以控制foreach 語句的循環結構,通過適當的拓展可以獲得指定情況下遍歷的結果。就例如,PHP提供搜索,遞歸,聚集,XMl等各類型的迭代器。種類繁多,功能齊全,比如要處理個XML,用個simplexmliterator 就立馬見效。
PHP5增加一個新的擴展叫SPL。SPL提供了很多的迭代器。迭代是一種設計模式。其精要在於: 提供一些統一的接口供外部對象訪問容器(container)裡面的元素,外部訪問對象無需知曉此容器裡的細節。
那容器(container)主要有那些元素呢? 就我理解,在PHP中,下列數據可以看成容器裡面的元素。
1、關聯數組(key=>value)
2、文件數據(如CSV)
3、目錄下的文件
4、XML元素和數據庫裡查詢的數據結果集
5、數據庫查詢結果集
要了解SPL提供的迭代器。需要先來看看SPL迭代器接口。SPL迭代器接口的作用在於可以實現高級的迭代算法,創建數據訪問方法。是迭起器的基礎。主要提供了以下幾個接口。
下面介紹一下最基礎的幾個迭代器的接口:
例子:
//本例子使用內置接口,無須再聲明
class MyClass {
public $var1 = 'value 1';
public $var2 = 'value 2';
public $var3 = 'value 3';
protected $protected = 'protected var';
private $private = 'private var';
function iterateVisible() {
echo "MyClass::iterateVisible:";
foreach ( $this as $key => $value ) {
print "$key => $value"." ";
}
}
}
$class = new MyClass ( );
foreach ( $class as $key => $value ) {
print "$key => $value"."<br/>";
}
$class->iterateVisible ();
OuterIterator extends Iterator {
/* Methods 返回當前正在迭代訪問的迭代器*/
public Iterator getInnerIterator ( void )
/* Inherited methods */
abstract public mixed Iterator::current ( void )
abstract public scalar Iterator::key ( void )
abstract public void Iterator::next ( void )
abstract public void Iterator::rewind ( void )
abstract public boolean Iterator::valid ( void )
}
RecursiveIterator extends Iterator {
/* 獲取子元素的一個迭代器的實例*/
public RecursiveIterator getChildren ( void )
/*判斷是否是繼續遞歸操作還是返回*/
public bool hasChildren ( void )
/* Inherited methods */
abstract public mixed Iterator::current ( void )
abstract public scalar Iterator::key ( void )
abstract public void Iterator::next ( void )
abstract public void Iterator::rewind ( void )
abstract public boolean Iterator::valid ( void )
}
Countable {
/* Methods */
abstract public int count ( void )
}
此接口繼承了Iterator接口的同時,提供了seek()方法,可以將內部指針指向任意元素。具體的接口方法如下:
SeekableIterator extends Iterator {
/* Methods */
abstract public void seek ( int $position )
/* Inherited methods */
abstract public mixed Iterator::current ( void )
abstract public scalar Iterator::key ( void )
abstract public void Iterator::next ( void )
abstract public void Iterator::rewind ( void )
abstract public boolean Iterator::valid ( void )
}
一個簡單的例子:
class MyIterator implements Iterator{
protected $position;
protected $arr;
public function __construct($array){
$this->arr = $array;
$this->postion = 0;
}
public function rewind(){
var_dump(__METHOD__);
$this->position = 0;
}
public function valid(){
var_dump(__METHOD__);
return isset($this->arr[$this->position]);
}
public function key(){
var_dump(__METHOD__);
return $this->position;
}
public function current(){
var_dump(__METHOD__);
return $this->arr[$this->position];
}
public function next(){
var_dump(__METHOD__);
return ++$this->position;
}
}
例子:
$array = array(1,2,3,3,4);
$it = new MyIterator($array);
foreach($it as $key=>$value){
echo $key.':'.$value.'<br/>';
}
使用iteratoraggregate :
class MyIteratorAggregate implements IteratorAggregate{
protected $arr;
public function __construct($array){
$this->arr = $array;
}
public function getIterator(){
return new MyIterator($this->arr);
}
}
例子:
$array = array(1,2,3,3,4);
$it = new MyIteratorAggregate($array);
foreach($it as $key=>$value){
echo $key.':'.$value.'<br/>';
}
對於PHP其他的那些迭代器,實在多不勝數,我反反復復查詢官網的手冊,終於整理出大體的結構草圖,在這裡分享給各位吧。
其實,之前我又在思考一個問題,為什麼要使用迭代器,我們不可以在foreach中去實現我們想要的處理呢。 其實,以上迭代器它本身的實現都是通過C拓展的,所以自己編寫的遍歷和PHP自身提供的迭代器是有性能的差異,第二個,因為遍歷的是對象而不是數組,面不來我們在遍歷的時候遇到不少麻煩,即使我們解決了,也不能確保我們應用到的算法是最好的,而迭代器就是集成了最優化的算法。所以,以後開發中盡量使用迭代器去做想做的事情吧。