SPL提供了多个迭代器类,分别提供了迭代访问、过滤数据、缓存结果、控制分页等功能。,因为php总是在不断壮大,我尽可能列出SPL中所有的迭代类。下面其中一些迭代器类是需要php5.4,另外一些如SearhIteratoer类在最新的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
) )
**/

2. LimitIterator

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

<示例>

 // 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
*/

3. AppendIterator

按顺序迭代访问几个不同的迭代器。例如,希望在一次循环中迭代访问两个或者更多的组合。这个迭代器的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 ($iterator as $current) {
echo $current."\n";
}
/**output
a
b
c
d
e
f
*/

4. FilterIterator

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

 class UserFilter extends FilterIterator
{
private $userFilter; public function __construct(Iterator $iterator, $filter)
{
parent::__construct($iterator);
$this->userFilter = $filter;
} public function 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 ($iterator as $result) {
echo $result['name'];
} /**output
Jonathan
**/

5. RegexIterator

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

 $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
)
**/

6. IteratorIterator

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

7. CachingIterator

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

 $array = array('koala', 'kangaroo', 'wombat', 'wallaby', 'emu', 'kiwi', 'kookaburra', 'platypus');
try {
$object = new CachingIterator(new ArrayIterator($array));
foreach ($object as $value) {
echo $value;
if ($object->hasNext()) {
echo ',';
}
}
}
catch (Exception $e) {
echo $e->getMessage();
}
/**output
koala,kangaroo,wombat,wallaby,emu,kiwi,kookaburra,platypus
**/

8. SeekableIterator

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

 $array = array("apple", "banana", "cherry", "damson", "elderberry");
$iterator = new ArrayIterator($array);
$iterator->seek(3);
echo $iterator->current();
/**output
damson
**/

9. NoRewindIterator

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

 $fruit = array('apple', 'banana', 'cranberry');
$arr = new ArrayObject($fruit);
$it = new NoRewindIterator($arr->getIterator());
echo "Fruit A:\n";
foreach ($it as $item) {
echo $item . "\n";
} echo "Fruit B:\n";
foreach ($it as $item) {
echo $item . "\n";
}
/**output
Fruit A:
apple
banana
cranberry
Fruit B:
**/

10. EmptyIterator

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

11. InfiniteIterator

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

 $arrayit = new ArrayIterator(array('cat', 'dog'));
$infinite = new InfiniteIterator($arrayit);
$limit = new LimitIterator($infinite, 0, 7);
foreach ($limit as $value) {
echo "$value\n";
}
/**output
cat
dog
cat
dog
cat
dog
cat
**/

12. RecursiveArrayIterator

创建一个用于递归形式数组结构的迭代器,类似于多维数组.它为许多更复杂的迭代器提供了所需的操作,如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
**/

13. RecursiveIteratorIterator

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

 $fruits = array("a" => "lemon", "b" => "orange", array("a" => "apple", "p" => "pear"));
$arrayiter = new RecursiveArrayIterator($fruits);
$iteriter = new RecursiveIteratorIterator($arrayiter);
foreach ($iteriter as $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
**/

14. RecursiveTreeIterator

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

 $hey = array("a" => "lemon", "b" => "orange", array("a" => "apple", "p" => "pear"));
$awesome = new RecursiveTreeIterator(
new RecursiveArrayIterator($hey),
null, null, RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($awesome as $line)
echo $line . PHP_EOL; /**output
|-lemon
|-orange
|-apple
\-pear
**/

15. ParentIterator

是一个扩展的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
)
)
**/

16. RecursiveFilterIterator

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

 class TestsOnlyFilter extends RecursiveFilterIterator
{
public function 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
)
**/

17. RecursiveRegexIterator

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

 $rArrayIterator = new RecursiveArrayIterator(array('叶1', array('tet3', '叶4', '叶5')));
$rRegexIterator = new RecursiveRegexIterator($rArrayIterator, '/^叶/',
RecursiveRegexIterator::ALL_MATCHES); foreach ($rRegexIterator as $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
**/

18. RecursiveCachingIterator

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

19. CallbackFilterIterator(PHP5.4)

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

 $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
)
**/

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

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

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

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

检查当前位置是否合法

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

22. FilesystemIterator

是DirectoryIterator的遍历器

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

23. GlobIterator

带匹配模式的文件遍历器

//找出../目录中.php扩展名的文件
$iterator = new GlobIterator('./*.php');
if (!$iterator->count()) {
echo '无php文件';
} else {
$n = 0;
printf("总计 %d 个php文件\r\n", $iterator->count());
foreach ($iterator as $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
**/

24. MultipleIterator

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

 $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"; //
foreach ($mit as $person) {
print_r($person);
}
/**output
Array
(
[ID] => 001
[NAME] => 张三
[AGE] => 22
)
Array
(
[ID] => 002
[NAME] => 李四
[AGE] => 23
)
Array
(
[ID] => 003
[NAME] => 王五
[AGE] => 11
)
**/

25. RecursiveCallbackFilterIterator(PHP5.4)

在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;
}

26. SimpleXMLIterator

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
) )
**/

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. Java实现中文字符串的排序功能

    package test; /** * * @Title 书的信息类 * @author LR * @version 1.0 * @since 2016-04-21 */ public class B ...

  2. Redhat=》中文

    我的redhat安装时没有提示语言选项,由于工程需要,支持汉字是不可避免的,因此就必须安装中文输入法. 安装中文包 将系统光盘镜像文件连接至计算机,我的镜像是RHEL5.1的,先将光盘挂载至/mnt目 ...

  3. ESB 客户端调用 处理类

    esb package com.isoftstone.synchronize.entrance; import java.io.File; import java.text.SimpleDateFor ...

  4. Live m3u8播放3个文件自动停止问题

    Live m3u8播放3个文件自动停止问题 1.问题描述 最近做一个转码切片播放测试,使用HLS(HTTP Live Streaming)来做直播, 每个TS分片时间为10s,根据TS分片文件生成以下 ...

  5. 关于 mobile sui a外链 老是出现加载失败的解决办法

    mobile sui 框架里面的a本身都绑了了一个ajax方法,ajax只能处理同域,跨域就会出现问题 ,所以mobile sui 中的a如果是外链的话就会出现加载失败的提示,这种明显的bug,让用户 ...

  6. 26.怎样在Swift中定义宏?

    Swift 中没有宏定义,苹果建议使用let 或者 get 属性来替代宏定义值.虽然没有#define,但我们仍然可以使用 #if 并配合编译的配置来完成条件编译.下面会列出Swift项目开发中的一些 ...

  7. Jquery基础:append、prepend、after、before、appendTo的区别

    append() 是在被选元素的结束标签前面(即改被选元素的内部)插入指定内容. after() 是在被选元素的结束标签后面(即该被选元素的外部)插入指定的内容. appendTo() 仍然是在被选元 ...

  8. javaScript 获取主机地址,项目名等

    //获取当前网址  var curWwwPath=window.document.location.href; alert(curWwwPath);  //http://localhost:8080/ ...

  9. ExtJs非Iframe框架加载页面实现

    在用Ext开发App应用时,一般的框架都是左边为菜单栏,中间为tab页方式的显示区域.而tab页面大多采用的嵌入一个iframe来显示内容.但是采用iframe方式有一个很大的弊端就是每次在加载一个新 ...

  10. 全代码实现ios-1

    第一次接触ios开发时,就决定用代码开发,而不用ib.因为被ib的各种控件的联线弄得一头雾水,而且ib和storyboard变动太快了. 开始的时候真是麻烦,因为网上关于全代码开发的例子太少了,大多数 ...