• 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 "
    ";
    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."
    ";
     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:
    ";
     5 foreach ($it as $item) {
     6     echo $item . "
    ";
     7 }
     8 
     9 echo "Fruit B:
    ";
    10 foreach ($it as $item) {
    11     echo $item . "
    ";
    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
    ";
     6 }
     7 /**output
     8 cat
     9 dog
    10 cat
    11 dog
    12 cat
    13 dog
    14 cat
    15  **/

    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 . "
    ";
            }
        } else {
            echo "No children.
    ";
        }
        $iterator->next();
    }
    
    /**output
    No children.
    No children.
    a : apple
    p : pear
     **/

    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
    ";
     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 "
    ";
    13     } else {
    14         echo "No children
    ";
    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 . "
    ";
    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
    ";
    6 }

    22. FilesystemIterator

    DirectoryIterator的遍历器

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

    23. GlobIterator

    带匹配模式的文件遍历器

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

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

     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() . "
    "; //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($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  **/
  • 相关阅读:
    通俗算法教程04
    微软是如何重写C#编译器并使它开源的
    在 CentOS 7 中安装 MySQL 8
    在 .NET Core 中结合 HttpClientFactory 使用 Polly(下篇)
    在 .NET Core 中结合 HttpClientFactory 使用 Polly(中篇)
    .NET 开源项目 Polly 介绍
    在 .NET Core 中结合 HttpClientFactory 使用 Polly(上篇)
    5年后、10年后,你希望自己是个什么样的人?
    即将发布的 ASP.NET Core 2.2 会有哪些新玩意儿?
    推荐六本前端开发必看的书籍
  • 原文地址:https://www.cnblogs.com/xingmeng/p/3583204.html
Copyright © 2020-2023  润新知