SPL提供了多個迭代器類,分別提供了迭代訪問、過濾數據、緩存結果、控制分頁等功能。,由於php老是在不斷壯大,我儘量列出SPL中全部的迭代類。下面其中一些迭代器類是須要php5.4,另一些如SearhIteratoer類在最新的php版本中已經去除php
1.ArrayIteratoer正則表達式
從PHP數組建立一個迭代器,當其和IteratorAggregate類一塊兒使用時,免去了直接實現Iterator接口的方法的工做。數組
<示例>緩存
$b = array( 'name'=> 'mengzhi', 'age' => '12', 'city'=> 'shanghai' ); $a = new ArrayIterator($b); $a->append(array( 'home' => 'china', 'work' => 'developer' )); $c = $a->getArrayCopy(); print_r($a); print_r($c); /**output ArrayIterator Object ( [storage:ArrayIterator:private] => Array ( [name] => mengzhi [age] => 12 [city] => shanghai [0] => Array ( [home] => china [work] => developer ) ) ) Array ( [name] => mengzhi [age] => 12 [city] => shanghai [0] => Array ( [home] => china [work] => developer ) ) **/
返回給定數量的結果以及從集合中取出結果的起始索引點:app
<示例>koa
// Create an iterator to be limited $fruits = new ArrayIterator(array( 'apple', 'banana', 'cherry', 'damson', 'elderberry' )); // Loop over first three fruits only foreach (new LimitIterator($fruits, 0, 3) as$fruit) { var_dump($fruit); } echo"\n"; // Loop from third fruit until the end // Note: offset starts from zero for apple foreach (new LimitIterator($fruits, 2) as$fruit) { print_r($fruit); } /**output string(5) "apple" string(6) "banana" string(6) "cherry" cherrydamsonelderberry */
按順序迭代訪問幾個不一樣的迭代器。例如,但願在一次循環中迭代訪問兩個或者更多的組合。這個迭代器的append方法相似於array_merge()函數來合併數組。函數
$array_a = new ArrayIterator(array('a', 'b', 'c')); $array_b = new ArrayIterator(array('d', 'e', 'f')); $iterator = new AppendIterator; $iterator->append($array_a); $iterator->append($array_b); foreach ($iteratoras$current) { echo$current."\n"; } /**output a b c d e f */
基於OuterIterator接口,用於過濾數據,返回符合條件的元素。必須實現一個抽象方法accept(),此方法必須爲迭代器的當前項返回true或falseoop
class UserFilter extends FilterIterator { private$userFilter; publicfunction __construct(Iterator $iterator, $filter) { parent::__construct($iterator); $this->userFilter = $filter; } publicfunction accept() { $user = $this->getInnerIterator()->current(); if (strcasecmp($user['name'], $this->userFilter) == 0) { return false; } return true; } } $array = array( array( 'name' => 'Jonathan', 'id' => '5' ), array( 'name' => 'Abdul', 'id' => '22' ) ); $object = new ArrayObject($array); //去除掉名爲abdul的人員 $iterator = new UserFilter($object->getIterator(), 'abdul'); foreach ($iteratoras$result) { echo$result['name']; } /**output Jonathan **/
繼承FilterIterator,支持使用正則表達式模式匹配和修改迭代器中的元素。常常用於將字符串匹配。ui
$a = new ArrayIterator(array('test1', 'test2', 'test3')); $i = new RegexIterator($a, '/^(test)(\d+)/', RegexIterator::REPLACE); $i->replacement = '$2:$1'; print_r(iterator_to_array($i)); /**output Array ( [0] => 1:test [1] => 2:test [2] => 3:test ) **/
一種通用類型的迭代器,全部實現了Traversable接口的類均可以被它迭代訪問。this
用來執行提早讀取一個元素的迭代操做,例如能夠用於肯定當前元素是否爲最後一個元素。
$array = array('koala', 'kangaroo', 'wombat', 'wallaby', 'emu', 'kiwi', 'kookaburra', 'platypus'); try { $object = new CachingIterator(new ArrayIterator($array)); foreach ($objectas$value) { echo$value; if ($object->hasNext()) { echo','; } } } catch (Exception $e) { echo$e->getMessage(); } /**output koala,kangaroo,wombat,wallaby,emu,kiwi,kookaburra,platypus **/
用於建立非順序訪問的迭代器,容許跳轉到迭代器中的任何一點上。
$array = array("apple", "banana", "cherry", "damson", "elderberry"); $iterator = new ArrayIterator($array); $iterator->seek(3); echo$iterator->current(); /**output damson **/
用於不能屢次迭代的集合,適用於在迭代過程當中執行一次性操做。
$fruit = array('apple', 'banana', 'cranberry'); $arr = new ArrayObject($fruit); $it = new NoRewindIterator($arr->getIterator()); echo"Fruit A:\n"; foreach ($itas$item) { echo$item . "\n"; } echo"Fruit B:\n"; foreach ($itas$item) { echo$item . "\n"; } /**output Fruit A: apple banana cranberry Fruit B: **/
一種佔位符形式的迭代器,不執行任何操做。當要實現某個抽象類的方法而且這個方法須要返回一個迭代器時,能夠使用這種迭代器。
用於持續地訪問數據,當迭代到最後一個元素時,會再次從第一個元素開始迭代訪問。
$arrayit = new ArrayIterator(array('cat', 'dog')); $infinite = new InfiniteIterator($arrayit); $limit = new LimitIterator($infinite, 0, 7); foreach ($limitas$value) { echo"$value\n"; } /**output cat dog cat dog cat dog cat **/
建立一個用於遞歸形式數組結構的迭代器,相似於多維數組.它爲許多更復雜的迭代器提供了所需的操做,如RecursiveTreeIterator和RecursiveIteratorIterator迭代器。
$fruits = array("a" => "lemon", "b" => "orange", array("a" => "apple", "p" => "pear")); $iterator = new RecursiveArrayIterator($fruits); while ($iterator->valid()) { //檢查是否含有子節點 if ($iterator->hasChildren()) { //輸出因此字節點 foreach ($iterator->getChildren() as$key => $value) { echo$key . ' : ' . $value . "\n"; } } else { echo"No children.\n"; } $iterator->next(); } /**output No children. No children. a : apple p : pear **/
將一個樹形結構的迭代器展開爲一維結構。
$fruits = array("a" => "lemon", "b" => "orange", array("a" => "apple", "p" => "pear")); $arrayiter = new RecursiveArrayIterator($fruits); $iteriter = new RecursiveIteratorIterator($arrayiter); foreach ($iteriteras$key => $value) { $d = $iteriter->getDepth(); echo"depth=$d k=$key v=$value\n"; } /**output depth=0 k=a v=lemon depth=0 k=b v=orange depth=1 k=a v=apple depth=1 k=p v=pear **/
以可視在方式顯示一個樹形結構。
$hey = array("a" => "lemon", "b" => "orange", array("a" => "apple", "p" => "pear")); $awesome = new RecursiveTreeIterator( new RecursiveArrayIterator($hey), null, null, RecursiveIteratorIterator::LEAVES_ONLY ); foreach ($awesomeas$line) echo$line . PHP_EOL; /**output |-lemon |-orange |-apple \-pear **/
是一個擴展的FilterIterator迭代器,它能夠過濾掉來自於RecursiveIterator迭代器的非父元素,只找出子節點的鍵值。通俗來講,就是去枝留葉。
$hey = array("a" => "lemon", "b" => "orange", array("a" => "apple", "p" => "pear")); $arrayIterator = new RecursiveArrayIterator($hey); $it = new ParentIterator($arrayIterator); print_r(iterator_to_array($it)); /**output Array ( [0] => Array ( [a] => apple [p] => pear ) ) **/
是FilterIterator迭代器的遞歸形式,也要求實現抽象的accept()方法,但在這個方法中應該使用$this->getInnerIterator()方法訪問當前正在迭代的迭代器。
class TestsOnlyFilter extends RecursiveFilterIterator { publicfunction accept() { // 找出含有「葉」的元素 return$this->hasChildren() || (mb_strpos($this->current(), "葉") !== FALSE); } } $array = array("葉1", array("李2", "葉3", "葉4"), "葉5"); $iterator = new RecursiveArrayIterator($array); $filter = new TestsOnlyFilter($iterator); $filter = new RecursiveIteratorIterator($filter); print_r(iterator_to_array($filter)); /**output Array ( [0] => 葉1 [1] => 葉3 [2] => 葉5 ) **/
是RegexIterator迭代器的遞歸形式,只接受RecursiveIterator迭代器做爲迭代對象。
$rArrayIterator = new RecursiveArrayIterator(array('葉1', array('tet3', '葉4', '葉5'))); $rRegexIterator = new RecursiveRegexIterator($rArrayIterator, '/^葉/', RecursiveRegexIterator::ALL_MATCHES); foreach ($rRegexIteratoras$key1 => $value1) { if ($rRegexIterator->hasChildren()) { // print all children echo"Children: "; foreach ($rRegexIterator->getChildren() as$key => $value) { echo$value . " "; } echo"\n"; } else { echo"No children\n"; } } /**output No children Children: 葉4 葉5 **/
在RecursiveIterator迭代器上執行提早讀取一個元素的遞歸操做。
同時執行過濾和回調操做,在找到一個匹配的元素以後會調用回調函數。
$hey = array( "李1", "葉2", "葉3", "葉4", "葉5", "葉6",); $arrayIterator = new RecursiveArrayIterator($hey); function isYe($current) { return mb_strpos($current,'葉') !== false; } $rs = new CallbackFilterIterator($arrayIterator, 'isYe'); print_r(iterator_to_array($rs)); /**output Array ( [0] => 葉2 [1] => 葉3 [2] => 葉4 [3] => 葉5 [4] => 葉6 ) **/
目錄文件遍歷器
方 法
描 述
DirectoryIterator::getSize
獲得文件大小
DirectoryIterator::getType
獲得文件類型
DirectoryIterator::isDir
若是當前項是一個目錄,返回true
DirectoryIterator::isDot
若是當前項是.或..,返回true
DirectoryIterator::isExecutable
若是文件可執行,返回true
DirectoryIterator::isFile
若是文件是一個常規文件,返回true
DirectoryIterator::isLink
若是文件是一個符號連接,返回true
DirectoryIterator::isReadable
若是文件可讀,返回true
DirectoryIterator::isWritable
若是文件可寫,返回true
DirectoryIterator::key
返回當前目錄項
DirectoryIterator::next
移動到下一項
DirectoryIterator::rewind
將目錄指針返回到開始位置
DirectoryIterator::valid
檢查目錄中是否包含更多項
$it = new DirectoryIterator("../"); foreach ($itas$file) { //用isDot ()方法分別過濾掉「.」和「..」目錄 if (!$it->isDot()) { echo$file . "\n"; } }
遞歸目錄文件遍歷器,可實現列出全部目錄層次結構,而不是隻操做一個目錄。
方 法
描 述
RecursiveDirectoryIterator::getChildren
若是這是一個目錄,爲當前項返回一個迭代器
RecursiveDirectoryIterator::hasChildren
返回當前項是不是一個目錄而不是.或..
RecursiveDirectoryIterator::key
返回當前目錄項的路徑和文件名
RecursiveDirectoryIterator::next
移動到下一項
RecursiveDirectoryIterator::rewind
將目錄指針返回到開始位置
RecursiveIteratorIterator::current
訪問當前元素值
RecursiveIteratorIterator::getDepth
獲得遞歸迭代的當前深度
RecursiveIteratorIterator::getSubIterator
獲得當前活動子迭代器
RecursiveIteratorIterator::key
訪問當前鍵
RecursiveIteratorIterator::next
前移到下一個元素
RecursiveIteratorIterator::rewind
將迭代器返回到頂級內層迭代器的第一個元素
RecursiveIteratorIterator::valid
檢查當前位置是否合法
//列出指定目錄中全部文件 $path = realpath('../'); $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST); foreach ($objectsas$name => $object) { echo"$name\n"; }
是DirectoryIterator的遍歷器
$it = new FilesystemIterator('../'); foreach ($itas$fileinfo) { echo$fileinfo->getFilename() . "\n"; }
帶匹配模式的文件遍歷器
//找出../目錄中.php擴展名的文件 $iterator = new GlobIterator('./*.php'); if (!$iterator->count()) { echo'無php文件'; } else { $n = 0; printf("總計 %d 個php文件\r\n", $iterator->count()); foreach ($iteratoras$item) { printf("[%d] %s\r\n", ++$n, $iterator->key()); } } /**output 總計 23 個php文件 [1] .\1.php [2] .\11.php [3] .\12.php [4] .\13.php [5] .\14.php [6] .\15.php [7] .\16.php [8] .\17.php [9] .\19.php [10] .\2.php [11] .\20.php [12] .\21.php [13] .\22.php [14] .\23.php [15] .\24.php [16] .\25.php [17] .\26.php [18] .\3.php [19] .\4.php [20] .\5.php [21] .\7.php [22] .\8.php [23] .\9.php **/
用於迭代器的鏈接器,具體看示例
$person_id = new ArrayIterator(array('001', '002', '003')); $person_name = new ArrayIterator(array('張三', '李四', '王五')); $person_age = new ArrayIterator(array(22, 23, 11)); $mit = new MultipleIterator(MultipleIterator::MIT_KEYS_ASSOC); $mit->attachIterator($person_id, "ID"); $mit->attachIterator($person_name, "NAME"); $mit->attachIterator($person_age, "AGE"); echo"鏈接的迭代器個數:".$mit->countIterators() . "\n"; //3 foreach ($mitas$person) { print_r($person); } /**output Array ( [ID] => 001 [NAME] => 張三 [AGE] => 22 ) Array ( [ID] => 002 [NAME] => 李四 [AGE] => 23 ) Array ( [ID] => 003 [NAME] => 王五 [AGE] => 11 ) **/
在RecursiveIterator迭代器上進行遞歸操做,同時執行過濾和回調操做,在找到一個匹配的元素以後會調用回調函數。
function doesntStartWithLetterT($current) { $rs = $current->getFileName(); return$rs[0] !== 'T'; } $rdi = new RecursiveDirectoryIterator(__DIR__); $files = new RecursiveCallbackFilterIterator($rdi, 'doesntStartWithLetterT'); foreach (new RecursiveIteratorIterator($files) as$file) { echo$file->getPathname() . PHP_EOL; }
XMl文檔訪問迭代器,可實現訪問xml中全部節點
$xml = <<<XML <books> <book> <title>PHP Basics</title> <author>Jim Smith</author> </book> <book>XML basics</book> </books> XML; // SimpleXML轉換爲數組 function sxiToArray($sxi) { $a = array(); for ($sxi->rewind(); $sxi->valid(); $sxi->next()) { if (!array_key_exists($sxi->key(), $a)) { $a[$sxi->key()] = array(); } if ($sxi->hasChildren()) { $a[$sxi->key()][] = sxiToArray($sxi->current()); } else { $a[$sxi->key()][] = strval($sxi->current()); } } return$a; } $xmlIterator = new SimpleXMLIterator($xml); $rs = sxiToArray($xmlIterator); print_r($rs); /**output Array ( [book] => Array ( [0] => Array ( [title] => Array ( [0] => PHP Basics ) [author] => Array ( [0] => Jim Smith ) ) [1] => XML basics ) ) **/