2015-04-04 2 views
0

У меня есть следующие структуры каталоговСделать Вложенный массив подкаталогов с помощью RecursiveDirectoryIterator

test 
    directory_in_test 
    directory_in_directory_in_test 
    directory2_in_test 
    directory_in_directory2_in_test 
    abc.php 
index.php 

Я пытаюсь сделать функцию, которая даст многомерный массив подкаталогов. Требуемая мощность что-то вроде:

[directories] => Array(
    [test] => Array(
     [directory_in_test] => Array(
      [directory_in_directory_in_test] => null 
     ) 
     [directory2_in_test] => Array(
      [directory_in_directory2_in_test] => null 
     )  
    ) 
) 

Я попытался использовали RecursiveIteratorIterator с RecursiveDirectoryIterator, но он дает массив одноуровневый каталогов и файлов, которые далеко от моего требования. Вот код, и результат у меня есть

код

<?php 
    public function findDirectories($path = '', $like = '') 
    { 
     $path = (is_dir($path)) ? $path : getcwd(); 
     $directories = array(); 
     $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path)); 
     foreach ($iterator as $directory) { 
      if($directory->isDir()) 
       $directories[] = $directory->getPathName(); 
     } 

     return $directories; 
    } 

Результат на полиграфических $ каталогами

Array 
(
    [0] => D:\xampp\htdocs\raheelwp\file-resolver\tests\. 
    [1] => D:\xampp\htdocs\raheelwp\file-resolver\tests\.. 
    [2] => D:\xampp\htdocs\raheelwp\file-resolver\tests\directory2_in_test\. 
    [3] => D:\xampp\htdocs\raheelwp\file-resolver\tests\directory2_in_test\.. 
    [4] => D:\xampp\htdocs\raheelwp\file-resolver\tests\directory2_in_test\directory_in_directory2_in_test\. 
    [5] => D:\xampp\htdocs\raheelwp\file-resolver\tests\directory2_in_test\directory_in_directory2_in_test\.. 
    [6] => D:\xampp\htdocs\raheelwp\file-resolver\tests\directory_in_test\. 
    [7] => D:\xampp\htdocs\raheelwp\file-resolver\tests\directory_in_test\.. 
    [8] => D:\xampp\htdocs\raheelwp\file-resolver\tests\directory_in_test\direcotry_in_directory_in_test\. 
    [9] => D:\xampp\htdocs\raheelwp\file-resolver\tests\directory_in_test\direcotry_in_directory_in_test\.. 
) 

ответ

0
<?php 

$it = new RecursiveDirectoryIterator(".", RecursiveDirectoryIterator::SKIP_DOTS); 
$it = new RecursiveIteratorIterator($it); 

$files = new RecursiveArrayIterator(array()); 
foreach ($it as $fi) { 
    $it = $files; 
    $dirs = explode('/', $fi->getPath()); 
    foreach ($dirs as $path) { 
     if (isset($it[$path])) { 
      $it = $it[$path]; 
     } else { 
      $it[$path] = new RecursiveArrayIterator(); 
     } 
    } 

    $it[$fi->getFileName()] = $fi->getFileName(); 
} 



$a = array(); 
createArray($a, $files); 
print_r($a); 

function createArray(&$a, $it) { 
    foreach ($it as $k => $tmp) { 
     if (is_string($tmp)) { 
      $a[] = $tmp; 
     } else { 
      $a[$k] = array(); 
      createArray($a[$k], $tmp); 
     } 
    } 
} 

код довольно прост, и разделить на две части даже если он может быть легко создан только в одной части. Первая часть разделит каталоги на отдельные RecursiveArrayIterators, поэтому вы сохраните возможности «итератора», чтобы делать с ними всевозможные вещи. Это часто полезно, когда вы используете Итераторы SPL для начала.

Вторая часть, функция createArray в основном использует ссылку массива для указания на «текущий» каталог. Поскольку это будет многомерный массив, нам не нужно беспокоиться о «где» в массиве, который мы на самом деле (это может быть 1-й уровень, это может быть 100-й уровень, если ваша структура каталогов будет настолько глубокой). Он просто проверяет, является ли данный элемент строкой, если это так, это файл, иначе это каталог, поэтому мы рекурсивно снова вызываем createArray.

Могут быть более легкие решения, но я считаю, что большинство из них все же использует базовую систему отсчета массива.