xuol001 发表于 2015-8-28 09:33:12

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]
查看完整版本: Php SPL库 的迭代器类详解【转】