Php SPL库 的迭代器类详解【转】
Php-SPL库中的迭代器类详解SPL提供了多个迭代器类,分别提供了迭代访问、过滤数据、缓存结果、控制分页等功能。,因为php总是在不断壮大,我尽可能列出SPL中所有的迭代类。下面其中一些迭代器类是需要php5.4,另外一些如SearhIteratoer类在最新的php版本中已经去除
1.ArrayIteratoer
从PHP数组创建一个迭代器,当其和IteratorAggregate类一起使用时,免去了直接实现Iterator接口的方法的工作。
<示例>
view plaincopy
[*]$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
[*](
[*] => Array
[*] (
[*] => mengzhi
[*] => 12
[*] => shanghai
[*] => Array
[*] (
[*] => china
[*] => developer
[*] )
[*]
[*] )
[*]
[*])
[*]Array
[*] (
[*] => mengzhi
[*] => 12
[*] => shanghai
[*] => Array
[*] (
[*] => china
[*] => developer
[*] )
[*]
[*])
[*]**/
2. LimitIterator
返回给定数量的结果以及从集合中取出结果的起始索引点:
<示例>
view plaincopy
[*]// 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()函数来合并数组。
view plaincopy
[*]$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
[*] */
4. FilterIterator
基于OuterIterator接口,用于过滤数据,返回符合条件的元素。必须实现一个抽象方法accept(),此方法必须为迭代器的当前项返回true或false
view plaincopy
[*]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
[*]**/
5. RegexIterator
继承FilterIterator,支持使用正则表达式模式匹配和修改迭代器中的元素。经常用于将字符串匹配。
view plaincopy
[*]$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
[*](
[*] => 1:test
[*] => 2:test
[*] => 3:test
[*])
[*] **/
6. IteratorIterator
一种通用类型的迭代器,所有实现了Traversable接口的类都可以被它迭代访问。
7. CachingIterator
用来执行提前读取一个元素的迭代操作,例如可以用于确定当前元素是否为最后一个元素。
view plaincopy
[*]$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
[*] **/
8. SeekableIterator
用于创建非顺序访问的迭代器,允许跳转到迭代器中的任何一点上。
view plaincopy
[*]$array = array("apple", "banana", "cherry", "damson", "elderberry");
[*]$iterator = new ArrayIterator($array);
[*]$iterator->seek(3);
[*]echo$iterator->current();
[*]/**output
[*]damson
[*] **/
9. NoRewindIterator
用于不能多次迭代的集合,适用于在迭代过程中执行一次性操作。
view plaincopy
[*]$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:
[*] **/
10. EmptyIterator
一种占位符形式的迭代器,不执行任何操作。当要实现某个抽象类的方法并且这个方法需要返回一个迭代器时,可以使用这种迭代器。
11. InfiniteIterator
用于持续地访问数据,当迭代到最后一个元素时,会再次从第一个元素开始迭代访问。
view plaincopy
[*]$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
[*] **/
12. RecursiveArrayIterator
创建一个用于递归形式数组结构的迭代器,类似于多维数组.它为许多更复杂的迭代器提供了所需的操作,如RecursiveTreeIterator和RecursiveIteratorIterator迭代器。
view plaincopy
[*]$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
将一个树形结构的迭代器展开为一维结构。
view plaincopy
[*]$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
[*] **/
14. RecursiveTreeIterator
以可视在方式显示一个树形结构。
view plaincopy
[*]$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
[*] **/
15. ParentIterator
是一个扩展的FilterIterator迭代器,它可以过滤掉来自于RecursiveIterator迭代器的非父元素,只找出子节点的键值。通俗来说,就是去枝留叶。
view plaincopy
[*]$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
[*] (
[*] => Array
[*] (
[*] => apple
[*] => pear
[*] )
[*])
[*] **/
16. RecursiveFilterIterator
是FilterIterator迭代器的递归形式,也要求实现抽象的accept()方法,但在这个方法中应该使用$this->getInnerIterator()方法访问当前正在迭代的迭代器。
view plaincopy
[*]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
[*](
[*] => 叶1
[*] => 叶3
[*] => 叶5
[*])
[*]**/
17. RecursiveRegexIterator
是RegexIterator迭代器的递归形式,只接受RecursiveIterator迭代器作为迭代对象。
view plaincopy
[*]$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
[*] **/
18. RecursiveCachingIterator
在RecursiveIterator迭代器上执行提前读取一个元素的递归操作。
19. CallbackFilterIterator(PHP5.4)
同时执行过滤和回调操作,在找到一个匹配的元素之后会调用回调函数。
view plaincopy
[*]$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
[*](
[*] => 叶2
[*] => 叶3
[*] => 叶4
[*] => 叶5
[*] => 叶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
检查目录中是否包含更多项
view plaincopy
[*]$it = new DirectoryIterator("../");
[*]foreach ($itas$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
检查当前位置是否合法
view plaincopy
[*]//列出指定目录中所有文件
[*]$path = realpath('../');
[*]$objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
[*]foreach ($objectsas$name => $object) {
[*] echo"$name\n";
[*]}
22. FilesystemIterator
是DirectoryIterator的遍历器
view plaincopy
[*]$it = new FilesystemIterator('../');
[*]foreach ($itas$fileinfo) {
[*] echo$fileinfo->getFilename() . "\n";
[*]}
23. GlobIterator
带匹配模式的文件遍历器
view plaincopy
[*]//找出../目录中.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.php
[*] .\11.php
[*] .\12.php
[*] .\13.php
[*] .\14.php
[*] .\15.php
[*] .\16.php
[*] .\17.php
[*] .\19.php
[*] .\2.php
[*] .\20.php
[*] .\21.php
[*] .\22.php
[*] .\23.php
[*] .\24.php
[*] .\25.php
[*] .\26.php
[*] .\3.php
[*] .\4.php
[*] .\5.php
[*] .\7.php
[*] .\8.php
[*] .\9.php
[*] **/
24. MultipleIterator
用于迭代器的连接器,具体看示例
view plaincopy
[*]$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
[*](
[*] => 001
[*] => 张三
[*] => 22
[*])
[*]Array
[*](
[*] => 002
[*] => 李四
[*] => 23
[*])
[*]Array
[*](
[*] => 003
[*] => 王五
[*] => 11
[*])
[*] **/
25. RecursiveCallbackFilterIterator(PHP5.4)
在RecursiveIterator迭代器上进行递归操作,同时执行过滤和回调操作,在找到一个匹配的元素之后会调用回调函数。
view plaincopy
[*]function doesntStartWithLetterT($current)
[*]{
[*] $rs = $current->getFileName();
[*] return$rs !== '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中所有节点
view plaincopy
[*]$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
[*](
[*] => Array
[*] (
[*] => Array
[*] (
[*] => Array
[*] (
[*] => PHP Basics
[*] )
[*]
[*] => Array
[*] (
[*] => Jim Smith
[*] )
[*]
[*] )
[*]
[*] => XML basics
[*] )
[*]
[*])
[*] **/
转:http://blog.iyunv.com/uuleaf/article/details/7635996
页:
[1]