2016-12-24 2 views
1

Я попытался написать собственный итератор массива с фабричным классом PHP. Моя проблема: Мне нужна все буи всех ДАННЫЕ, например, вот простой PHP массив:PHP RecursiveArrayIterator класс get key-value pair recursive

Array 
(
    [authentication] => Array 
     (
      [basic] => Array 
       (
        [username] => guest 
        [password] => guest 
       ) 

      [filters] => Array 
       (
        [price] => 100 
        [owener] => me 
       ) 

     ) 

) 

я вижу на странице дока PHP, я могу использовать два простые класс и перебирать с простым Еогеаспом:

$iterator = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($this->phpArray)); 
    foreach($iterator as $key => $value) { 
     $d = $iterator->getDepth(); 
     echo "depth: $d $key => $value\n"; 
    } 

Эта программа бросить следующий вывод:

depth: 2 key: username, value: guest 
depth: 2 key: password, value: guest 
depth: 2 key: price, value: 100 
depth: 2 key: owener, value: me 

Как изменить мой код, что может сделать следующий пример вывода со всеми DATAS:

depth: 0 key: authentication, value: 
depth: 1 key: basic, value: 
depth: 1 key: filters, 
depth: 2 key: username, value: guest 
depth: 2 key: password, value: guest 
depth: 2 key: price, value: 100 
depth: 2 key: owener, value: me 

Спасибо!

ответ

1

При использовании RecursiveIteratorIterator вы можете установить различные режимы траверса. По умолчанию используется номер RecursiveIteratorIterator::LEAVES_ONLY. Вот почему вы получаете только листья, но не все значения (кстати, array_walk_recursive имеет такое же поведение). Чтобы посетить все элементы, которые необходимо установить режим RecursiveIteratorIterator::SELF_FIRST:

$iterator = new \RecursiveIteratorIterator(
    new \RecursiveArrayIterator($array), 
    \RecursiveIteratorIterator::SELF_FIRST 
); 

Вот working demo.

+0

Большое спасибо sevavieti, отлично работает! :) – Gabor

+0

@ Габор, пожалуйста. Итераторы действительно плохо документированы, и это трудно понять. – sevavietl

1

В качестве альтернативы можно использовать рекурсивную функцию следующим образом:

function traverseArray($arr, &$depthArray, $depth = 0){ 
    foreach($arr as $key => $value){ 
     if(is_array($value)){ 
      $depthArray[$depth][] = array('depth' => $depth, 'key' => $key, 'value' => ''); 
      traverseArray($value, $depthArray, ++$depth); 
      --$depth; 
     }else{ 
      $depthArray[$depth][] = array('depth' => $depth, 'key' => $key, 'value' => $value); 
     } 
    } 
} 

Создать пустой массив с именем $depthArray и вызывать эту функцию с двумя аргументами, первым из них будет ваш исходный массив $this->phpArray и второй один будет это $depthArray, как это:

$depthArray = array(); 
traverseArray($this->phpArray, $depthArray); 

Наконец, используйте вложенные foreach петли для обхода $depthArray и дисплей ключ, значение и связанное с ним глубина этого элемента, например:

foreach($depthArray as $depth => $arr){ 
    foreach($arr as $a){ 
     echo 'depth:' . $a['depth'] . ' key: ' . $a['key'] . ' value: ' . $a['value'] . '<br />'; 
    } 
} 
Смежные вопросы