什麼是SPLphp
S
tandard P
HP L
ibrarySPL: 用於解決常見廣泛問題的一組接口與類的集合數組
Common Problem:數據結構
數學建模/數據結構app
元素遍歷框架
經常使用方法的統一調用函數
類定義的自動裝載工具
SPL的基本框架this
Bottom:最早添加到鏈表中的節點叫作Bottom
(底部),也稱爲頭部(head
)
Top:最後添加到鏈表中得節點叫作top
頂部,也稱爲尾部
鏈表指針:是一個當前關注的節點的標識,能夠指向任意節點
當前指針:鏈表指針指向的節點稱爲當前節點
節點名稱:能夠在鏈表中惟一標識一個節點的名稱,咱們一般又稱爲節點的key
或offset
節點數據:存放在鏈表中的應用數據,一般稱爲value
spa
/** * 雙向鏈表 */ $obj = new SplDoublyLinkedList(); $obj->push(4); $obj->push(6); $obj->unshift(66); print_r($obj);
SplDoublyLinkedList Object ( [flags:SplDoublyLinkedList:private] => 0 [dllist:SplDoublyLinkedList:private] => Array ( [0] => 66 [1] => 4 [2] => 6 ) )
雙向鏈表經常使用方法:
Bottom: 得到鏈表底部(頭部)元素,當前指針位置不變
Top: 獲取鏈表頂部(尾部)元素,當前指針位置不變
Push: 往鏈表頂部(Top
)中追加節點
Pop: 把top
位置的節點從鏈表中刪除,操做不改變當前指針的位置
Unshif: 往鏈表底部追加節點(Bottom
)
Shif: 刪除鏈表底部的節點
Rewind: 把節點指針指向Bottom
所在的節點
Current: 指向鏈表當前節點的指針,必須
在調用以前先調用rewind
。當指向的節點被刪除以後,會指向一個空節點
Next: 指針指向下一個節點,current
的返回值隨之改變
Prev: 指針指向上一個節點,current
的返回值隨之改變3d
雙向鏈表判斷當前節點是否有效節點方法:
if(雙向鏈表對象.current()) 有效 else 無效
或
//用$obj->current()判斷當前是否有迭代元素很差,由於當元素值是false,0,或者空字符時 //他們效果和null同樣,區分不了,因此嚴謹的話要使用valid方法判斷 if(雙向鏈表對象.valid()) 有效 else 無效
繼承自SplDoublyLinkedList類的SplStack類
操做:
- `push`:壓入堆棧(存入) - `pop`:退出堆棧(取出)
堆棧:單端出入,先進後出 Fist In Last Out(FILO
)
/** * 堆棧 */ $obj = new SplStack(); $obj->push(2); $obj->push('test'); $obj->push(6); print_r($obj);
SplStack Object ( [flags:SplDoublyLinkedList:private] => 6 [dllist:SplDoublyLinkedList:private] => Array ( [0] => 2 [1] => test [2] => 6 ) )
經常使用操做:
Bottom(): 最早進入的元素;
Top(): 最後進入的元素;
offSet(0): 是top
的位置
rewind(): 把top
的元素置爲current()
的位置
注意:
- 堆棧的`rewind()`指向`top`,雙向鏈表的`rewind()`指向`bottom` - 堆棧和雙向鏈表都有`next`方法,方向相反
隊列和堆棧恰好相反,最早進入隊列的元素會最早走出隊列
繼承自SplDoublyLinkedList
類的SqlQueue
類
操做:
- `enqueue`:進入隊列 - `dequeue`:退出隊列
/** * 隊列 */ $obj = new SplQueue(); $obj->enqueue('a'); $obj->enqueue('b'); $obj->enqueue('c'); print_r($obj);
SplQueue Object ( [flags:SplDoublyLinkedList:private] => 4 [dllist:SplDoublyLinkedList:private] => Array ( [0] => a [1] => b [2] => c ) )
經常使用操做:
enqueue: 插入一個節點到隊列裏面的top
位置
dequeue: 操做從隊列中提取Bottom
位置的節點,同時從隊列裏面刪除該元素
offSet(0): 是Bottom
所在的位置
rewind: 操做使得指針指向Bottom
所在的位置的節點
next: 操做使得當前指針指向Top
方向的下一個節點
經過某種
統一的方式
遍歷鏈表或則數組中的元素的過程叫作迭代遍歷,這種統一的遍歷工具叫迭代器
PHP
中迭代器是經過Iterator
接口定義的
ArrayIterator
迭代器用於遍歷數組
seek()
,指針定位到某個位置,很實用,跳過前面n-1
的元素ksort()
,對key
進行字典序排序asort()
,對值
進行字典序排序$arr=array( 'apple' => 'apple value', // position = 0 'orange' => 'orange value', // position = 1 'grape' => 'grape value', 'plum' => 'plum value' ); $obj=new ArrayObject($arr); $it =$obj->getIterator();//生成數組的迭代器。 foreach ($it as $key => $value){ echo $key . ":". $value .'<br />'; } echo '<br />'; //實現和foreach一樣功能 $it->rewind();// 調用current以前必定要調用rewind While($it->valid()){//判斷當前是否爲有效數據 echo $it->key().' : '.$it->current().'<br />'; $it->next();//千萬不能少 } //實現更復雜功能,跳過某些元素進行打印 $it->rewind(); if ($it->valid()){ $it->seek(1);//position,跳過前面 n-1的元素 While($it->valid()){//判斷當前是否爲有效數據 echo $it->key().' : '.$it->current().'<br />'; $it->next();//千萬不能少 } } $it->ksort();//對key進行字典序排序 //$it->asort();//對值進行字典序排序 foreach ($it as $key => $value){ echo $key . ":". $value .'<br />'; }
foreach
本質會自動生成一個迭代器,只是使用了迭代器的最長用功能,若是要實現複雜需求,foreach
實現不了,就須要手動生成迭代器對象來使用了
好比,要從一個大數組中取出一部分數據,foreach
比較困難,除非他知道數據的樣子。將數組或者集合中的所有或者一部數據取出來,用迭代器比較方便
AppendIterator
能陸續遍歷幾個迭代器
$arr_a = new ArrayIterator(array('a'=> array('a','b'=>234),'b','c')); $arr_b = new ArrayIterator(array('d','e','f')); $it = new AppendIterator(); $it->append($arr_a);//追加數組 $it->append($arr_b);//追加數組,而後遍歷$it foreach ($it as $key => $value){ print_r($value); }
用於把多個Iterator
裏面的數據組合成爲一個總體來訪問
Multipleiterator
將多個arrayiterator
拼湊起來 Appenditerator
將多個arrayiteratorr
鏈接起來 $idIter = new ArrayIterator(array('01','02','03')); $nameIter = new ArrayIterator(array('張三','李四','王五')); $ageIter = new ArrayIterator(array('22','23','25')); $mit = new MultipleIterator(MultipleIterator::MIT_KEYS_ASSOC);//按照key關聯 $mit->attachIterator($idIter,"ID"); $mit->attachIterator($nameIter,"NAME"); $mit->attachIterator($ageIter,"AGE"); foreach ($mit as $value){ print_r($value); }
Array ( [ID] => 01 [NAME] => 張三 [AGE] => 22 ) Array ( [ID] => 02 [NAME] => 李四 [AGE] => 23 ) Array ( [ID] => 03 [NAME] => 王五 [AGE] => 25 )
filesystemIterator
seek
方法定位到集合裏面的某個特定元素 在代碼裏面常常能夠直接用count($obj)
方法獲取對象裏面的元素個數
count(array('name'=>'Peter','id'=>'5'));
對於咱們定義的類,也能這樣訪問嗎?
count
函數,可是沒有繼承countable
接口,直接用count
函數時,不會調用對象自定義的count
若是對象自己也有count
函數,同時對象也繼承了countable
接口,直接用count
函數時,會調用對象自身的count
函數,效果至關與:對象->count()
count()
是Countable
必須實現的接口count(Countable $obj)
返回是類內部的count()
返回的結果,其會被強制轉成int
$arr = array( array('name' => 'name value', 'id' => 2), array('name' => 'Peter', 'id' => 4, 'age' => 22), ); echo count($arr); echo count($arr[1]); class CountMe implements Countable { protected $myCount = 6; protected $myCount2 = 3; protected $myCount3 = 2; public function count() { // TODO: Implement count() method. return $this->myCount; } } $obj = new CountMe(); echo count($obj); //6
OuterIterator接口
IteratorIterator
類是OuterIterator
的實現,擴展的時候,能夠直接繼承IteratorIterator
$array = ['Value1','Value2','Value3','Value4']; $outerObj = new OuterImpl(new ArrayIterator($array)); foreach ($outerObj as $key => $value){ echo "++".$key.'-'.$value."\n"; } class OuterImpl extends IteratorIterator { public function current() { return parent::current()."_tail"; } public function key() { return "Pre_".parent::key(); } }
++Pre_0-Value1_tail ++Pre_1-Value2_tail ++Pre_2-Value3_tail ++Pre_3-Value4_tail
完!