PHP: как заполнить структуру каталогов в массиве

Я разрабатываю панель администратора, которая показывает структуру каталогов определенного места на сервере. У меня есть рекурсивная функция php, которая выполняет итерацию через каждый файл и папку. Я не могу понять, как сохранить эту структуру каталогов в ассоциативном массиве php следующим образом:

array[foldername1][0]=file; // if the foldername1 contains a file array[foldername1][foldername2][0]=file //if foldername1 contains another folder(foldername2) along with the file. 

Правило, которое я пытаюсь выполнить, – это; папка всегда должна быть ключом, и файл всегда должен иметь такой индекс:

 array[folder1][folder2][0]=file1; array[folder1][folder2][1]=file2; 

Функция для заполнения этого ассоциативного массива должна быть общей, так как мы никогда не знаем, какова структура каталогов. Я хочу, чтобы json_encode этот массив возвращался к моему клиенту и разбирался с ним в javascript, который не является проблемой на данный момент.

Если это плохой подход, пожалуйста, дайте мне знать, что может быть лучший способ сделать это. Я думал об использовании плоского массива, но я думаю, что это плохой дизайн.

 $ritit = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(__DIR__), RecursiveIteratorIterator::CHILD_FIRST); $r = array(); foreach ($ritit as $splFileInfo) { $path = $splFileInfo->isDir() ? array($splFileInfo->getFilename() => array()) : array($splFileInfo->getFilename()); for ($depth = $ritit->getDepth() - 1; $depth >= 0; $depth--) { $path = array($ritit->getSubIterator($depth)->current()->getFilename() => $path); } $r = array_merge_recursive($r, $path); } print_r($r); 

Этот класс, чтобы захватить файлы и каталоги рекурсивными (= включая поддиры), поместив пути в один полезный массив, даст вам хороший головной убор:

  class myRecursiveDirectoryParser { protected $currentPath; protected $slash; protected $rootPath; protected $recursiveTree; function __construct($rootPath,$win=false) { switch($win) { case true: $this->slash = '\\'; break; default: $this->slash = '/'; } $this->rootPath = $rootPath; $this->currentPath = $rootPath; $this->recursiveTree = array(dir($this->rootPath)); $this->rewind(); } function __destruct() { $this->close(); } public function close() { while(true === ($d = array_pop($this->recursiveTree))) { $d->close(); } } public function closeChildren() { while(count($this->recursiveTree)>1 && false !== ($d = array_pop($this->recursiveTree))) { $d->close(); return true; } return false; } public function getRootPath() { if(isset($this->rootPath)) { return $this->rootPath; } return false; } public function getCurrentPath() { if(isset($this->currentPath)) { return $this->currentPath; } return false; } public function read() { while(count($this->recursiveTree)>0) { $d = end($this->recursiveTree); if((false !== ($entry = $d->read()))) { if($entry!='.' && $entry!='..') { $path = $d->path.$entry; if(is_file($path)) { return $path; } elseif(is_dir($path.$this->slash)) { $this->currentPath = $path.$this->slash; if($child = @dir($path.$this->slash)) { $this->recursiveTree[] = $child; } } } } else { array_pop($this->recursiveTree)->close(); } } return false; } public function rewind() { $this->closeChildren(); $this->rewindCurrent(); } public function rewindCurrent() { return end($this->recursiveTree)->rewind(); } } в  class myRecursiveDirectoryParser { protected $currentPath; protected $slash; protected $rootPath; protected $recursiveTree; function __construct($rootPath,$win=false) { switch($win) { case true: $this->slash = '\\'; break; default: $this->slash = '/'; } $this->rootPath = $rootPath; $this->currentPath = $rootPath; $this->recursiveTree = array(dir($this->rootPath)); $this->rewind(); } function __destruct() { $this->close(); } public function close() { while(true === ($d = array_pop($this->recursiveTree))) { $d->close(); } } public function closeChildren() { while(count($this->recursiveTree)>1 && false !== ($d = array_pop($this->recursiveTree))) { $d->close(); return true; } return false; } public function getRootPath() { if(isset($this->rootPath)) { return $this->rootPath; } return false; } public function getCurrentPath() { if(isset($this->currentPath)) { return $this->currentPath; } return false; } public function read() { while(count($this->recursiveTree)>0) { $d = end($this->recursiveTree); if((false !== ($entry = $d->read()))) { if($entry!='.' && $entry!='..') { $path = $d->path.$entry; if(is_file($path)) { return $path; } elseif(is_dir($path.$this->slash)) { $this->currentPath = $path.$this->slash; if($child = @dir($path.$this->slash)) { $this->recursiveTree[] = $child; } } } } else { array_pop($this->recursiveTree)->close(); } } return false; } public function rewind() { $this->closeChildren(); $this->rewindCurrent(); } public function rewindCurrent() { return end($this->recursiveTree)->rewind(); } } 

Далее приведен пример использования класса. В вашем случае вам нужно будет пройти данные, использовать «explode ('/')» в цикле и построить новый массив, как вы описали выше.

  $d = new myRecursiveDirectoryParser("./",false); echo($d->getRootPath() . "<br>"); while (false !== ($entry = $d->read())) { echo($entry."<br>"); } $d->close(); 

Все, что вам нужно сделать, это заняться. Вы почти закончили, когда вы берете его отсюда. 😉

Вы можете попробовать это, где $ dir – указанный путь:

 function dir_tree($dir) { $path = ''; $stack[] = $dir; while ($stack) { $thisdir = array_pop($stack); if ($dircont = scandir($thisdir)) { $i=0; while (isset($dircont[$i])) { if ($dircont[$i] !== '.' && $dircont[$i] !== '..') { $current_file = "{$thisdir}/{$dircont[$i]}"; if (is_file($current_file)) { $path[] = "{$thisdir}/{$dircont[$i]}"; } elseif (is_dir($current_file)) { $path[] = "{$thisdir}/{$dircont[$i]}"; $stack[] = $current_file; } } $i++; } } } return $path; } 

Я создал сущность класса дерева сборки. Он использует RecursiveDirectoryIterator и создает массив или JSON для цели ajax.

Вот он: https://gist.github.com/jonataswalker/3c0c6b26eabb2e36bc90