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(),此方法必须为迭代器的当前项返回true或false

  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"; //
  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($files) as $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. **/

Php-SPL库中的迭代器类详解(转)的更多相关文章

  1. MFC中CString.Format类详解

    在MFC程序中,使用CString来处理字符串是一个很不错的选择.CString既可以处理Unicode标准的字符串,也可以处理ANSI标准的字符串.CString的Format方法给我们进行字符串的 ...

  2. hadoop中典型Writable类详解

    本文地址:http://www.cnblogs.com/archimedes/p/hadoop-writable.html,转载请注明源地址. Hadoop将很多Writable类归入org.apac ...

  3. Spring框架spring-web模块中的RestTemplate类详解

    RestTemplate类是spring-web模块中进行HTTP访问的REST客户端核心类.RestTemplate请求使用阻塞式IO,适合低并发的应用场景. 1. RestTemplate类提供了 ...

  4. Sopus库中FindEigen3.cmake内容详解笔记

    FindEigen3.cmake: # - Try to find Eigen3 lib # Once done this will define # # EIGEN3_FOUND - system ...

  5. Delphi 中的 XMLDocument 类详解(10) - 判断节点类型: 支节点、叶节点、文本节点、空节点

    unit Unit1; interface uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, For ...

  6. Delphi 中的 XMLDocument 类详解(9) - 关于 HasChildNodes 与 IsTextElement

    unit Unit1; interface uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, For ...

  7. (14)javaWeb中的HttpServletResponse类详解

    如果希望了解请求和响应的详细内容,可以看我的“HTTP协议”系列文章 响应体的简单概述: a,响应报文结构: b,常见的状态码,返回服务器处理的结果: c,常见的响应头: HttpServletRes ...

  8. 在PHP中使用SPL库中的对象方法进行XML与数组的转换

    虽说现在很多的服务提供商都会提供 JSON 接口供我们使用,但是,还是有不少的服务依然必须使用 XML 作为接口格式,这就需要我们来对 XML 格式的数据进行解析转换.而 PHP 中并没有像 json ...

  9. JDK中Unsafe类详解

    Java中Unsafe类详解 在openjdk8下看Unsafe源码 浅析Java中的原子操作 Java并发编程之LockSupport http://hg.openjdk.java.net/jdk7 ...

随机推荐

  1. 开扒php内核函数,第二篇 hex2bin

    从上一篇我们得知怎样把ascii变成16进制显示,这篇我们是怎样把16进制变成ascii显示 我们还是从分析开始吧 先看这个函数的介绍吧 string hex2bin ( string $data ) ...

  2. [转] Web前端优化之 图片篇

    原文链接: http://lunax.info/archives/3101.html Web 前端优化最佳实践第六部分面向 图片(Image),这部分目前有 4 条规则.在最近的 Velocity 2 ...

  3. debug 64bit dump of a 32bit process in windows 7 64bit

    In Windows 7 the TaskMgr provides one easy way to create dump for the applications. You can right cl ...

  4. Android 相关

    ADT 下载更新 http://www.oschina.net/question/1463998_220998 更改包名后,资源文件不更新 AndroidMainfast.xml文件,有package ...

  5. Azure中的分布式1——多实例

    Azure中的WebRole和WorkerRole天然支持负载均衡,只需要简单配置一下即可,下面我以一个WebRole为例说明这一点. 创建一个项目类型为MVC4的WebRole 项目结构如下: 右键 ...

  6. Node.js V0.12 新特性之性能优化

    v0.12悠长的开发周期(已经过去九个月了,并且还在继续,是有史以来最长的一次)让核心团队和贡献者们有充分的机会对性能做一些优化. 本文会介绍其中最值得注意的几个. http://www.infoq. ...

  7. jquery cookie用法(获取cookie值,删除cookie)

    1.引入文件 2.具体操作 $.cookie('the_cookie'); // 读取 cookie $.cookie('the_cookie', 'the_value'); // 存储 cookie ...

  8. T-SQL 运行时生成语句

    运行时生成语句 1.用EXECUTE执行动态命令 EXECUTE命令可以执行存储过程.函数和动态的字符串命令.注意此语句的作用正如前面在介绍批处理时,如果批中的第一条语句是"EXECUTE存 ...

  9. win2008 64位 + oracle11G 64位 IIS7.5 配置WEBSERVICE

    第一个错误: 安装过程依旧是那样简单,但在配好IIS站点,准备连接数据库的时候出错了,以下是错误提示:System.Data.OracleClient 需要 Oracle 客户端软件 8.1.7 或更 ...

  10. non-manifold Mesh(非流形网格)

    三角网格曲面中,大多的算法基于流形网格manifold mesh,其定义如下: 1)Each edge is incident to only one or two faces: 一条网格边为一个或两 ...