Maison  >  Article  >  développement back-end  >  PHP SPL库 的迭代器类使用详解

PHP SPL库 的迭代器类使用详解

WBOY
WBOYoriginal
2016-06-20 13:03:26889parcourir

SPL是Standard PHP Library(PHP标准库)的缩写。

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 ($iteratoras$current) { 
    echo$current."\n"; 
} 
/**output
a
b
c
d
e
f
*/ 

4. FilterIterator

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


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,支持使用正则表达式模式匹配和修改迭代器中的元素。经常用于将字符串匹配。


$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 ($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

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

 

$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 ($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

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


$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迭代器。

$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 ($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

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


$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迭代器的非父元素,只找出子节点的键值。通俗来说,就是去枝留叶。

 

$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 
{ 
    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
(
    [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 ($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)

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


$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 ($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

检查当前位置是否合法

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

22. FilesystemIterator

是DirectoryIterator的遍历器


$it = new FilesystemIterator('../'); 
foreach ($itas$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 ($iteratoras$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"; //3 
foreach ($mitas$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
        )
)
**/ 

 


Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn