Php SPL库 的迭代器类详解

Php-SPL库中的迭代器类详解


SPL提供了多个迭代器类,分别提供了迭代访问、过滤数据、缓存结果、控制分页等功能。,因为php总是在不断壮大,我尽可能列出SPL中所有的迭代类。下面其中一些迭代器类是需要php5.4,另外一些如SearhIteratoer类在最新的php版本中已经去除

1.ArrayIteratoer

PHP数组创建一个迭代器,当其和IteratorAggregate类一起使用时,免去了直接实现Iterator接口的方法的工作。

<示例>

  1. $b = array(  
  2.     'name'=> 'mengzhi',  
  3.     'age' => '12',  
  4.     'city'=> 'shanghai'  
  5. );  
  6. $a = new ArrayIterator($b);  
  7. $a->append(array(  
  8.                 'home' => 'china',  
  9.                 'work' => 'developer'  
  10.            ));  
  11. $c = $a->getArrayCopy();  
  12. print_r($a);  
  13. print_r($c);  
  14.   
  15. /**output 
  16. ArrayIterator Object 
  17. ( 
  18.     [storage:ArrayIterator:private] => Array 
  19.     ( 
  20.     [name] => mengzhi 
  21.             [age] => 12 
  22.             [city] => shanghai 
  23.             [0] => Array 
  24.     ( 
  25.     [home] => china 
  26.                     [work] => developer 
  27.                 ) 
  28.  
  29.         ) 
  30.  
  31. ) 
  32. Array 
  33.     ( 
  34.     [name] => mengzhi 
  35.     [age] => 12 
  36.     [city] => shanghai 
  37.     [0] => Array 
  38.     ( 
  39.     [home] => china 
  40.             [work] => developer 
  41.         ) 
  42.  
  43. ) 
  44. **/  


2. LimitIterator

返回给定数量的结果以及从集合中取出结果的起始索引点:

<示例>

  1. // Create an iterator to be limited  
  2. $fruits = new ArrayIterator(array(  
  3.                                  'apple',  
  4.                                  'banana',  
  5.                                  'cherry',  
  6.                                  'damson',  
  7.                                  'elderberry'  
  8.                             ));  
  9. // Loop over first three fruits only  
  10. foreach (new LimitIterator($fruits, 0, 3) as $fruit) {  
  11.     var_dump($fruit);  
  12. }  
  13. echo "\n";  
  14. // Loop from third fruit until the end  
  15. // Note: offset starts from zero for apple  
  16. foreach (new LimitIterator($fruits, 2) as $fruit) {  
  17.     print_r($fruit);  
  18. }  
  19.   
  20. /**output 
  21. string(5) "apple" 
  22. string(6) "banana" 
  23. string(6) "cherry" 
  24.  
  25. cherrydamsonelderberry 
  26.  */  


3. AppendIterator

  按顺序迭代访问几个不同的迭代器。例如,希望在一次循环中迭代访问两个或者更多的组合。这个迭代器的append方法类似于array_merge()函数来合并数组。

  1. $array_a = new ArrayIterator(array('a''b''c'));  
  2. $array_b = new ArrayIterator(array('d''e''f'));  
  3. $iterator = new AppendIterator;  
  4. $iterator->append($array_a);  
  5. $iterator->append($array_b);  
  6. foreach ($iterator as $current) {  
  7.     echo $current."\n";  
  8. }  
  9. /**output 
  10. a 
  11. b 
  12. c 
  13. d 
  14. e 
  15. f 
  16.  */  


4. FilterIterator

基于OuterIterator接口,用于过滤数据,返回符合条件的元素。必须实现一个抽象方法accept(),此方法必须为迭代器的当前项返回truefalse

  1. class UserFilter extends FilterIterator  
  2. {  
  3.     private $userFilter;  
  4.   
  5.     public function __construct(Iterator $iterator$filter)  
  6.     {  
  7.         parent::__construct($iterator);  
  8.         $this->userFilter = $filter;  
  9.     }  
  10.   
  11.     public function accept()  
  12.     {  
  13.         $user = $this->getInnerIterator()->current();  
  14.         if (strcasecmp($user['name'], $this->userFilter) == 0) {  
  15.             return false;  
  16.         }  
  17.         return true;  
  18.     }  
  19. }  
  20.   
  21. $array = array(  
  22.     array(  
  23.         'name' => 'Jonathan',  
  24.         'id'   => '5'  
  25.     ),  
  26.     array(  
  27.         'name' => 'Abdul',  
  28.         'id'   => '22'  
  29.     )  
  30. );  
  31. $object = new ArrayObject($array);  
  32. //去除掉名为abdul的人员  
  33. $iterator = new UserFilter($object->getIterator(), 'abdul');  
  34. foreach ($iterator as $result) {  
  35.     echo $result['name'];  
  36. }  
  37.   
  38. /**output 
  39. Jonathan 
  40. **/  


5. RegexIterator

继承FilterIterator,支持使用正则表达式模式匹配和修改迭代器中的元素。经常用于将字符串匹配。

  1. $a = new ArrayIterator(array('test1''test2''test3'));  
  2. $i = new RegexIterator($a'/^(test)(\d+)/', RegexIterator::REPLACE);  
  3. $i->replacement = '$2:$1';  
  4. print_r(iterator_to_array($i));  
  5.   
  6. /**output 
  7. Array 
  8. ( 
  9.     [0] => 1:test 
  10.     [1] => 2:test 
  11.     [2] => 3:test 
  12. ) 
  13.  **/  

6. IteratorIterator

一种通用类型的迭代器,所有实现了Traversable接口的类都可以被它迭代访问。

7. CachingIterator

用来执行提前读取一个元素的迭代操作,例如可以用于确定当前元素是否为最后一个元素。

  1. $array = array('koala''kangaroo''wombat''wallaby''emu''kiwi''kookaburra''platypus');  
  2. try {  
  3.     $object = new CachingIterator(new ArrayIterator($array));  
  4.     foreach ($object as $value) {  
  5.         echo $value;  
  6.         if ($object->hasNext()) {  
  7.             echo ',';  
  8.         }  
  9.     }  
  10. }  
  11. catch (Exception $e) {  
  12.     echo $e->getMessage();  
  13. }  
  14. /**output 
  15. koala,kangaroo,wombat,wallaby,emu,kiwi,kookaburra,platypus 
  16.  **/  

8. SeekableIterator

用于创建非顺序访问的迭代器,允许跳转到迭代器中的任何一点上。

  1. $array = array("apple""banana""cherry""damson""elderberry");  
  2. $iterator = new ArrayIterator($array);  
  3. $iterator->seek(3);  
  4. echo $iterator->current();  
  5. /**output 
  6. damson 
  7.  **/  

9. NoRewindIterator

用于不能多次迭代的集合,适用于在迭代过程中执行一次性操作。

  1. $fruit = array('apple''banana''cranberry');  
  2. $arr = new ArrayObject($fruit);  
  3. $it = new NoRewindIterator($arr->getIterator());  
  4. echo "Fruit A:\n";  
  5. foreach ($it as $item) {  
  6.     echo $item . "\n";  
  7. }  
  8.   
  9. echo "Fruit B:\n";  
  10. foreach ($it as $item) {  
  11.     echo $item . "\n";  
  12. }  
  13. /**output 
  14. Fruit A: 
  15. apple 
  16. banana 
  17. cranberry 
  18. Fruit B: 
  19.  **/  


10. EmptyIterator

一种占位符形式的迭代器,不执行任何操作。当要实现某个抽象类的方法并且这个方法需要返回一个迭代器时,可以使用这种迭代器。

11. InfiniteIterator

用于持续地访问数据,当迭代到最后一个元素时,会再次从第一个元素开始迭代访问。

  1. $arrayit = new ArrayIterator(array('cat''dog'));  
  2. $infinite = new InfiniteIterator($arrayit);  
  3. $limit = new LimitIterator($infinite, 0, 7);  
  4. foreach ($limit as $value) {  
  5.     echo "$value\n";  
  6. }  
  7. /**output 
  8. cat 
  9. dog 
  10. cat 
  11. dog 
  12. cat 
  13. dog 
  14. cat 
  15.  **/  

12. RecursiveArrayIterator

创建一个用于递归形式数组结构的迭代器,类似于多维数组.它为许多更复杂的迭代器提供了所需的操作,如RecursiveTreeIterator和RecursiveIteratorIterator迭代器。

  1. $fruits = array("a" => "lemon""b" => "orange"array("a" => "apple""p" => "pear"));  
  2. $iterator = new RecursiveArrayIterator($fruits);  
  3. while ($iterator->valid()) {  
  4.     //检查是否含有子节点  
  5.     if ($iterator->hasChildren()) {  
  6.         //输出所以字节点  
  7.         foreach ($iterator->getChildren() as $key => $value) {  
  8.             echo $key . ' : ' . $value . "\n";  
  9.         }  
  10.     } else {  
  11.         echo "No children.\n";  
  12.     }  
  13.     $iterator->next();  
  14. }  
  15.   
  16. /**output 
  17. No children. 
  18. No children. 
  19. a : apple 
  20. p : pear 
  21.  **/  

13. RecursiveIteratorIterator

将一个树形结构的迭代器展开为一维结构。

  1. $fruits = array("a" => "lemon""b" => "orange"array("a" => "apple""p" => "pear"));  
  2. $arrayiter = new RecursiveArrayIterator($fruits);  
  3. $iteriter = new RecursiveIteratorIterator($arrayiter);  
  4. foreach ($iteriter as $key => $value) {  
  5.     $d = $iteriter->getDepth();  
  6.     echo "depth=$d k=$key v=$value\n";  
  7. }  
  8.   
  9. /**output 
  10. depth=0 k=a v=lemon 
  11. depth=0 k=b v=orange 
  12. depth=1 k=a v=apple 
  13. depth=1 k=p v=pear 
  14.  **/  


14. RecursiveTreeIterator

以可视在方式显示一个树形结构。

  1. $hey = array("a" => "lemon""b" => "orange"array("a" => "apple""p" => "pear"));  
  2. $awesome = new RecursiveTreeIterator(  
  3.     new RecursiveArrayIterator($hey),  
  4.     null, null, RecursiveIteratorIterator::LEAVES_ONLY  
  5. );  
  6. foreach ($awesome as $line)  
  7.     echo $line . PHP_EOL;  
  8.   
  9. /**output 
  10. |-lemon 
  11. |-orange 
  12.     |-apple 
  13.     \-pear 
  14.  **/  



15. ParentIterator

是一个扩展的FilterIterator迭代器,它可以过滤掉来自于RecursiveIterator迭代器的非父元素,只找出子节点的键值。通俗来说,就是去枝留叶。

  1. $hey = array("a" => "lemon""b" => "orange"array("a" => "apple""p" => "pear"));  
  2. $arrayIterator = new RecursiveArrayIterator($hey);  
  3. $it = new ParentIterator($arrayIterator);  
  4. print_r(iterator_to_array($it));  
  5. /**output 
  6. Array 
  7.     ( 
  8.     [0] => Array 
  9.     ( 
  10.         [a] => apple 
  11.         [p] => pear 
  12.     ) 
  13. ) 
  14.  **/  

16. RecursiveFilterIterator

FilterIterator迭代器的递归形式,也要求实现抽象的accept()方法,但在这个方法中应该使用$this->getInnerIterator()方法访问当前正在迭代的迭代器。

  1. class TestsOnlyFilter extends RecursiveFilterIterator  
  2. {  
  3.     public function accept()  
  4.     {  
  5.         // 找出含有“叶”的元素  
  6.         return $this->hasChildren() || (mb_strpos($this->current(), "叶") !== FALSE);  
  7.     }  
  8. }  
  9.   
  10. $array = array("叶1"array("李2""叶3""叶4"), "叶5");  
  11. $iterator = new RecursiveArrayIterator($array);  
  12. $filter = new TestsOnlyFilter($iterator);  
  13. $filter = new RecursiveIteratorIterator($filter);  
  14. print_r(iterator_to_array($filter));  
  15. /**output 
  16. Array 
  17. ( 
  18.     [0] => 叶1 
  19.     [1] => 叶3 
  20.     [2] => 叶5 
  21. ) 
  22. **/  


17. RecursiveRegexIterator

RegexIterator迭代器的递归形式,只接受RecursiveIterator迭代器作为迭代对象。

  1. $rArrayIterator = new RecursiveArrayIterator(array('叶1'array('tet3''叶4''叶5')));  
  2. $rRegexIterator = new RecursiveRegexIterator($rArrayIterator'/^叶/',  
  3.     RecursiveRegexIterator::ALL_MATCHES);  
  4.   
  5. foreach ($rRegexIterator as $key1 => $value1) {  
  6.     if ($rRegexIterator->hasChildren()) {  
  7.         // print all children  
  8.         echo "Children: ";  
  9.         foreach ($rRegexIterator->getChildren() as $key => $value) {  
  10.             echo $value . " ";  
  11.         }  
  12.         echo "\n";  
  13.     } else {  
  14.         echo "No children\n";  
  15.     }  
  16. }  
  17. /**output 
  18. No children 
  19. Children: 叶4 叶5  
  20.  **/  


18. RecursiveCachingIterator

在RecursiveIterator迭代器上执行提前读取一个元素的递归操作。


19. CallbackFilterIterator(PHP5.4)

同时执行过滤和回调操作,在找到一个匹配的元素之后会调用回调函数。

  1. $hey = array"李1""叶2""叶3""叶4""叶5""叶6",);  
  2. $arrayIterator = new RecursiveArrayIterator($hey);  
  3. function isYe($current)  
  4. {  
  5.     return mb_strpos($current,'叶') !== false;  
  6. }  
  7.   
  8. $rs = new CallbackFilterIterator($arrayIterator'isYe');  
  9. print_r(iterator_to_array($rs));  
  10.   
  11. /**output 
  12. Array 
  13. ( 
  14.     [0] => 叶2 
  15.     [1] => 叶3 
  16.     [2] => 叶4 
  17.     [3] => 叶5 
  18.     [4] => 叶6 
  19. ) 
  20.  **/  

20. DirectoryIterator

目录文件遍历器

方    法

描    述

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

检查目录中是否包含更多项


  1. $it = new DirectoryIterator("../");  
  2. foreach ($it as $file) {  
  3.     //用isDot ()方法分别过滤掉“.”和“..”目录  
  4.     if (!$it->isDot()) {  
  5.         echo $file . "\n";  
  6.     }  
  7. }  


21. RecursiveDirectoryIterator

递归目录文件遍历器,可实现列出所有目录层次结构,而不是只操作一个目录。

方    法

描    述

RecursiveDirectoryIterator::getChildren

如果这是一个目录,为当前项返回一个迭代器

RecursiveDirectoryIterator::hasChildren

返回当前项是否是一个目录而不是...

RecursiveDirectoryIterator::key

返回当前目录项的路径和文件名

RecursiveDirectoryIterator::next

移动到下一项

RecursiveDirectoryIterator::rewind

将目录指针返回到开始位置

RecursiveIteratorIterator::current

访问当前元素值

RecursiveIteratorIterator::getDepth

得到递归迭代的当前深度

RecursiveIteratorIterator::getSubIterator

得到当前活动子迭代器

RecursiveIteratorIterator::key

访问当前键

RecursiveIteratorIterator::next

前移到下一个元素

RecursiveIteratorIterator::rewind

将迭代器返回到顶级内层迭代器的第一个元素

RecursiveIteratorIterator::valid

检查当前位置是否合法


  1. //列出指定目录中所有文件  
  2. $path = realpath('../');  
  3. $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);  
  4. foreach ($objects as $name => $object) {  
  5.     echo "$name\n";  
  6. }  

22. FilesystemIterator

DirectoryIterator的遍历器

  1. $it = new FilesystemIterator('../');  
  2. foreach ($it as $fileinfo) {  
  3.     echo $fileinfo->getFilename() . "\n";  
  4. }  

23. GlobIterator

带匹配模式的文件遍历器

  1. //找出../目录中.php扩展名的文件  
  2. $iterator = new GlobIterator('./*.php');  
  3. if (!$iterator->count()) {  
  4.     echo '无php文件';  
  5. else {  
  6.     $n = 0;  
  7.     printf("总计 %d 个php文件\r\n"$iterator->count());  
  8.     foreach ($iterator as $item) {  
  9.         printf("[%d] %s\r\n", ++$n$iterator->key());  
  10.     }  
  11. }  
  12. /**output  
  13. 总计 23 个php文件  
  14. [1] .\1.php  
  15. [2] .\11.php  
  16. [3] .\12.php  
  17. [4] .\13.php  
  18. [5] .\14.php  
  19. [6] .\15.php  
  20. [7] .\16.php  
  21. [8] .\17.php  
  22. [9] .\19.php  
  23. [10] .\2.php  
  24. [11] .\20.php  
  25. [12] .\21.php  
  26. [13] .\22.php  
  27. [14] .\23.php  
  28. [15] .\24.php  
  29. [16] .\25.php  
  30. [17] .\26.php  
  31. [18] .\3.php  
  32. [19] .\4.php  
  33. [20] .\5.php  
  34. [21] .\7.php  
  35. [22] .\8.php  
  36. [23] .\9.php  
  37.  **/  

24. MultipleIterator

用于迭代器的连接器,具体看示例

  1. $person_id = new ArrayIterator(array('001''002''003'));  
  2. $person_name = new ArrayIterator(array('张三''李四''王五'));  
  3. $person_age = new ArrayIterator(array(22, 23, 11));  
  4. $mit = new MultipleIterator(MultipleIterator::MIT_KEYS_ASSOC);  
  5. $mit->attachIterator($person_id"ID");  
  6. $mit->attachIterator($person_name"NAME");  
  7. $mit->attachIterator($person_age"AGE");  
  8. echo "连接的迭代器个数:".$mit->countIterators() . "\n"//3  
  9. foreach ($mit as $person) {  
  10.     print_r($person);  
  11. }  
  12. /**output 
  13. Array 
  14. ( 
  15.     [ID] => 001 
  16.     [NAME] => 张三 
  17.     [AGE] => 22 
  18. ) 
  19. Array 
  20. ( 
  21.     [ID] => 002 
  22.     [NAME] => 李四 
  23.     [AGE] => 23 
  24. ) 
  25. Array 
  26. ( 
  27.     [ID] => 003 
  28.     [NAME] => 王五 
  29.     [AGE] => 11 
  30. ) 
  31.  **/  

25. RecursiveCallbackFilterIterator(PHP5.4)

RecursiveIterator迭代器上进行递归操作,同时执行过滤和回调操作,在找到一个匹配的元素之后会调用回调函数。

  1. function doesntStartWithLetterT($current)  
  2. {  
  3.     $rs = $current->getFileName();  
  4.     return $rs[0] !== 'T';  
  5. }  
  6.   
  7. $rdi = new RecursiveDirectoryIterator(__DIR__);  
  8. $files = new RecursiveCallbackFilterIterator($rdi'doesntStartWithLetterT');  
  9. foreach (new RecursiveIteratorIterator($filesas $file) {  
  10.     echo $file->getPathname() . PHP_EOL;  
  11. }  


26. SimpleXMLIterator

XMl文档访问迭代器,可实现访问xml中所有节点

  1. $xml = <<<XML  
  2. <books>  
  3.     <book>  
  4.         <title>PHP Basics</title>  
  5.         <author>Jim Smith</author>  
  6.     </book>  
  7.     <book>XML basics</book>  
  8. </books>  
  9. XML;  
  10. // SimpleXML转换为数组  
  11. function sxiToArray($sxi)  
  12. {  
  13.     $a = array();  
  14.     for ($sxi->rewind(); $sxi->valid(); $sxi->next()) {  
  15.         if (!array_key_exists($sxi->key(), $a)) {  
  16.             $a[$sxi->key()] = array();  
  17.         }  
  18.         if ($sxi->hasChildren()) {  
  19.             $a[$sxi->key()][] = sxiToArray($sxi->current());  
  20.         } else {  
  21.             $a[$sxi->key()][] = strval($sxi->current());  
  22.         }  
  23.     }  
  24.     return $a;  
  25. }  
  26.   
  27. $xmlIterator = new SimpleXMLIterator($xml);  
  28. $rs = sxiToArray($xmlIterator);  
  29. print_r($rs);  
  30. /**output 
  31. Array 
  32. ( 
  33.     [book] => Array 
  34.         ( 
  35.             [0] => Array 
  36.                 ( 
  37.                     [title] => Array 
  38.                         ( 
  39.                             [0] => PHP Basics 
  40.                         ) 
  41.  
  42.                     [author] => Array 
  43.                         ( 
  44.                             [0] => Jim Smith 
  45.                         ) 
  46.  
  47.                 ) 
  48.  
  49.             [1] => XML basics 
  50.         ) 
  51.  
  52. ) 
  53.  **/ 
转:http://blog.csdn.net/uuleaf/article/details/7635996
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值