©
Ce document utilise Manuel du site Web PHP chinois Libérer
(PHP 5)
Can be used to iterate through recursive iterators.
$iterator
[, int $mode
= RecursiveIteratorIterator::LEAVES_ONLY
[, int $flags
= 0
]] )$level
] )$max_depth
= -1
] )RecursiveIteratorIterator::LEAVES_ONLY
RecursiveIteratorIterator::SELF_FIRST
RecursiveIteratorIterator::CHILD_FIRST
RecursiveIteratorIterator::CATCH_GET_CHILD
[#1] gerry at king-foo dot be [2014-06-11 12:44:03]
Carefull when using iterator_to_array(). Because it flattens down your subiterators, elements with the same keys will overwrite eachother.
For example:
<?php
$iterator = new RecursiveIteratorIterator(
new RecursiveArrayIterator([
['foo', 'bar'],
['baz', 'qux']
])
);
foreach ($iterator as $element) {
echo $element;
}
?>
This will output all 4 elements as expected:
string(3) "foo"
string(3) "bar"
string(3) "baz"
string(3) "qux"
While doing:
<?php
var_dump(iterator_to_array($iterator));
?>
will output an array with only the last 2 elements:
array(2) {
[0]=>
string(3) "baz"
[1]=>
string(3) "qux"
}
[#2] fengdingbo at gmail dot com [2013-08-21 02:18:41]
if you want traversal directory??
<?php
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator("./")) as $key=>$val)
{
echo $key,"=>",$val,"\n";
}
?>
[#3] zlobnygrif at gmail dot com [2013-07-16 06:06:00]
Some speed tests
<?php
$timer = function ($name = 'default', $unset_timer = TRUE)
{
static $timers = array();
if ( isset( $timers[ $name ] ) )
{
list($s_sec, $s_mic) = explode(' ', $timers[ $name ]);
list($e_sec, $e_mic) = explode(' ', microtime());
if ( $unset_timer )
unset( $timers[ $name ] );
return $e_sec - $s_sec + ( $e_mic - $s_mic );
}
$timers[ $name ] = microtime();
};
function f1 ($array) {
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array), RecursiveIteratorIterator::SELF_FIRST);
foreach ( $iterator as $key => $value ) {
if ( is_array($value) )
continue;
}
}
function f2($array) {
foreach ( $array as $key => $value ) {
if ( is_array($value) )
f2($value);
}
}
foreach ( [100, 1000, 10000, 100000, 1000000] as $num )
{
$array = [];
for ( $i = 0; ++$i < $num; )
$array[] = [1,2,3=>[4,5,6=>[7,8,9=>10,11,12=>[13,14,15=>[16,17,18]]]]];
$timer();
f1($array);
printf("RecursiveIteratorIterator: %7d elements -> %.3f sec\n", $num, $timer());
$timer();
f2($array);
printf("Recursive function : %7d elements -> %.3f sec\n", $num, $timer());
}
?>
Output (PHP 5.4.9-4ubuntu2.1 (cli) (built: Jun 11 2013 13:10:01))
=======================
RecursiveIteratorIterator: 100 elements -> 0.007 sec
Recursive function : 100 elements -> 0.002 sec
RecursiveIteratorIterator: 1000 elements -> 0.036 sec
Recursive function : 1000 elements -> 0.024 sec
RecursiveIteratorIterator: 10000 elements -> 0.425 sec
Recursive function : 10000 elements -> 0.263 sec
RecursiveIteratorIterator: 100000 elements -> 8.153 sec
Recursive function : 100000 elements -> 2.654 sec
RecursiveIteratorIterator: 1000000 elements -> 474.483 sec
Recursive function : 1000000 elements -> 26.872 sec
For one million elements recursive function is more quickly!
[#4] Adil Baig @ AIdezigns [2011-06-23 23:17:27]
A very important thing to note about \RecursiveIteratorIterator is that it returns a flattened array when used with the iterator_to_array function. Ex:
<?php
$arr = array('Zero', 'name'=>'Adil', 'address' => array( 'city'=>'Dubai', 'tel' => array('int' => 971, 'tel'=>12345487)), '' => 'nothing');
$iterator = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($arr));
var_dump(iterator_to_array($iterator,true));
?>
This code will return :
array(6) {
[0]=>
string(4) "Zero"
["name"]=>
string(4) "Adil"
["city"]=>
string(5) "Dubai"
["int"]=>
int(91)
["tel"]=>
int(12345487)
[""]=>
string(7) "nothing"
}
To get the non-flattened proper array use the getArrayCopy() method, like so :
$iterator->getArrayCopy()
This will return
array(4) {
[0]=>
string(4) "Zero"
["name"]=>
string(4) "Adil"
["address"]=>
array(2) {
["city"]=>
string(5) "Dubai"
["tel"]=>
array(2) {
["int"]=>
int(91)
["tel"]=>
int(12345487)
}
}
[""]=>
string(7) "nothing"
}
[#5] Tom [2011-01-06 01:35:26]
This class operates on a tree of elements, which is build by nesting recursive iterators into one another.
Thus you might say it is an iterator over iterators. While traversing those, the class pushes the iterators on a stack while traversing down to a leaf and removes them from the stack while going back up.
[#6] aidan at php dot net [2010-04-29 21:57:52]
This example demonstrates using the getDepth() method with a RecursiveArrayIterator.
<?php
$tree = array();
$tree[1][2][3] = 'lemon';
$tree[1][4] = 'melon';
$tree[2][3] = 'orange';
$tree[2][5] = 'grape';
$tree[3] = 'pineapple';
print_r($tree);
$arrayiter = new RecursiveArrayIterator($tree);
$iteriter = new RecursiveIteratorIterator($arrayiter);
foreach ($iteriter as $key => $value) {
$d = $iteriter->getDepth();
echo "depth=$d k=$key v=$value\n";
}
?>
The output of this would be:
Array
(
[1] => Array
(
[2] => Array
(
[3] => lemon
)
[4] => melon
)
[2] => Array
(
[3] => orange
[5] => grape
)
[3] => pineapple
)
depth=2 k=3 v=lemon
depth=1 k=4 v=melon
depth=1 k=3 v=orange
depth=1 k=5 v=grape
depth=0 k=3 v=pineapple
[#7] Michiel Brandenburg [2009-06-14 16:40:42]
You can use this to quickly find all the files (recursively) in a certain directory. This beats maintaining a stack yourself.
<?php
$directory = "/tmp/";
$fileSPLObjects = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($directory),
RecursiveIteratorIterator::CHILD_FIRST
);
try {
foreach( $fileSPLObjects as $fullFileName => $fileSPLObject ) {
print $fullFileName . " " . $fileSPLObject->getFilename() . "\n";
}
}
catch (UnexpectedValueException $e) {
printf("Directory [%s] contained a directory we can not recurse into", $directory);
}
?>
Note: if there is a directory contained within the directory you are searching in that you have no access to read an UnexpectedValueException will be thrown (leaving you with an empty list).
Note: objects returned are SPLFileObjects
[#8] crashrox at gmail dot com [2008-12-19 09:51:01]
Recursive multidimensional array flatten using SPL
<?php
function array_flatten_recursive($array) {
if($array) {
$flat = array();
foreach(new RecursiveIteratorIterator(new RecursiveArrayIterator($array), RecursiveIteratorIterator::SELF_FIRST) as $key=>$value) {
if(!is_array($value)) {
$flat[] = $value;
}
}
return $flat;
} else {
return false;
}
}
$array = array(
'A' => array('B' => array( 1, 2, 3, 4, 5)),
'C' => array( 6,7,8,9)
);
print_r(array_flatten_recursive($array));
?>
-- Returns:
Array (
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
[6] => 7
[7] => 8
[8] => 9
)