Php-SPL库中的迭代器类详解(转)
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库中的迭代器类详解(转)的更多相关文章
- MFC中CString.Format类详解
在MFC程序中,使用CString来处理字符串是一个很不错的选择.CString既可以处理Unicode标准的字符串,也可以处理ANSI标准的字符串.CString的Format方法给我们进行字符串的 ...
- hadoop中典型Writable类详解
本文地址:http://www.cnblogs.com/archimedes/p/hadoop-writable.html,转载请注明源地址. Hadoop将很多Writable类归入org.apac ...
- Spring框架spring-web模块中的RestTemplate类详解
RestTemplate类是spring-web模块中进行HTTP访问的REST客户端核心类.RestTemplate请求使用阻塞式IO,适合低并发的应用场景. 1. RestTemplate类提供了 ...
- Sopus库中FindEigen3.cmake内容详解笔记
FindEigen3.cmake: # - Try to find Eigen3 lib # Once done this will define # # EIGEN3_FOUND - system ...
- Delphi 中的 XMLDocument 类详解(10) - 判断节点类型: 支节点、叶节点、文本节点、空节点
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, For ...
- Delphi 中的 XMLDocument 类详解(9) - 关于 HasChildNodes 与 IsTextElement
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, For ...
- (14)javaWeb中的HttpServletResponse类详解
如果希望了解请求和响应的详细内容,可以看我的“HTTP协议”系列文章 响应体的简单概述: a,响应报文结构: b,常见的状态码,返回服务器处理的结果: c,常见的响应头: HttpServletRes ...
- 在PHP中使用SPL库中的对象方法进行XML与数组的转换
虽说现在很多的服务提供商都会提供 JSON 接口供我们使用,但是,还是有不少的服务依然必须使用 XML 作为接口格式,这就需要我们来对 XML 格式的数据进行解析转换.而 PHP 中并没有像 json ...
- JDK中Unsafe类详解
Java中Unsafe类详解 在openjdk8下看Unsafe源码 浅析Java中的原子操作 Java并发编程之LockSupport http://hg.openjdk.java.net/jdk7 ...
随机推荐
- Spinlock
Spinlock From Wikipedia, the free encyclopedia This article needs additional citations for verificat ...
- jQuery文档加载完毕的几种写法
js中文档加载完毕.一般在body加一个onload事件或者window.onload = function () {} jQuery中有好多写法,平时也不注意,别人一问,还真觉得头大. 下面是我整理 ...
- 精美&创意的WordPress新发主题集合
今天我整理了一些精美&创意的WordPress新发主题,它们基本上都融合了最新的设计理念,从简约到响应式,应有尽有. Engo – Smart & Minimal WordPress ...
- 【Python学习笔记】字典操作
字典dict是Python中唯一内置的映射类型,由键值对组成,字典是无序的.字典的键必须是不变对象,如字符串.数字.元组等,而包含可变对象的列表.字典和元组则不能作为键.这里可变和不可变的意思是指这个 ...
- Python伪开发者对于搜狐云景的测评
Python伪开发者对于搜狐云景的测评 本人是GAE和OpenShift的狂热爱好者,玩过各种国外PaaS.某次想搞个稍微复杂点的Python Web程序,需要比较好的网络传输速度,就试图找前PM(P ...
- Uva 11183 - Teen Girl Squad (最小树形图)
Problem ITeen Girl Squad Input: Standard Input Output: Standard Output You are part of a group of n ...
- web缓存值varnish使用
具体的介绍到官网 https://www.varnish-software.com/static/book 一.简介 Varnish is a reverse HTTP proxy, sometime ...
- 第三百二十一天 how can I 坚持
上班第一天,感觉时间过得好慢. 心里好烦,做什么都没心情,感觉没有勇气了,虽然早上说了那么多,但不敢去面对了. 咋整? <猪老三><野子>. 好想去看<美人鱼> 不 ...
- sql操作table
1.增加表字段 alter table tbsptrustquotdoc(表名) add chargeapplystate(字段名) char(1)(类型) default '1'(默认值) 2. ...
- Mysql SQL优化&执行计划
SQL优化准则 禁用select * 使用select count(*) 统计行数 尽量少运算 尽量避免全表扫描,如果可以,在过滤列建立索引 尽量避免在where子句对字段进行null判断 尽量避免在 ...