Список всех файлов и папок в каталоге с рекурсивной функцией PHP

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

Код:

function getDirContents($dir){ $results = array(); $files = scandir($dir); foreach($files as $key => $value){ if(!is_dir($dir. DIRECTORY_SEPARATOR .$value)){ $results[] = $value; } else if(is_dir($dir. DIRECTORY_SEPARATOR .$value)) { $results[] = $value; getDirContents($dir. DIRECTORY_SEPARATOR .$value); } } } print_r(getDirContents('/xampp/htdocs/WORK')); 

Получите все файлы и папки в каталоге, не вызывайте функцию, когда у вас есть . или ..

Ваш код :

 <?php function getDirContents($dir, &$results = array()){ $files = scandir($dir); foreach($files as $key => $value){ $path = realpath($dir.DIRECTORY_SEPARATOR.$value); if(!is_dir($path)) { $results[] = $path; } else if($value != "." && $value != "..") { getDirContents($path, $results); $results[] = $path; } } return $results; } var_dump(getDirContents('/xampp/htdocs/WORK')); 

Выход (пример):

 array (size=12) 0 => string '/xampp/htdocs/WORK/iframe.html' (length=30) 1 => string '/xampp/htdocs/WORK/index.html' (length=29) 2 => string '/xampp/htdocs/WORK/js' (length=21) 3 => string '/xampp/htdocs/WORK/js/btwn.js' (length=29) 4 => string '/xampp/htdocs/WORK/js/qunit' (length=27) 5 => string '/xampp/htdocs/WORK/js/qunit/qunit.css' (length=37) 6 => string '/xampp/htdocs/WORK/js/qunit/qunit.js' (length=36) 7 => string '/xampp/htdocs/WORK/js/unit-test.js' (length=34) 8 => string '/xampp/htdocs/WORK/xxxxx.js' (length=30) 9 => string '/xampp/htdocs/WORK/plane.png' (length=28) 10 => string '/xampp/htdocs/WORK/qunit.html' (length=29) 11 => string '/xampp/htdocs/WORK/styles.less' (length=30) 
 $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator('path/to/folder')); $files = array(); foreach ($rii as $file) { if ($file->isDir()){ continue; } $files[] = $file->getPathname(); } var_dump($files); 

Это принесет вам все файлы с путями.

Это более короткая версия:

 function getDirContents($path) { $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)); $files = array(); foreach ($rii as $file) if (!$file->isDir()) $files[] = $file->getPathname(); return $files; } var_dump(getDirContents($path)); 

Получите все файлы с фильтром (2-й аргумент) и папки в каталоге, не вызывайте функцию, когда у вас есть . или ..

Ваш код :

 <?php function getDirContents($dir, $filter = '', &$results = array()) { $files = scandir($dir); foreach($files as $key => $value){ $path = realpath($dir.DIRECTORY_SEPARATOR.$value); if(!is_dir($path)) { if(empty($filter) || preg_match($filter, $path)) $results[] = $path; } elseif($value != "." && $value != "..") { getDirContents($path, $filter, $results); } } return $results; } // Simple Call: List all files var_dump(getDirContents('/xampp/htdocs/WORK')); // Regex Call: List php files only var_dump(getDirContents('/xampp/htdocs/WORK', '/\.php$/')); 

Выход (пример):

 // Simple Call array(13) { [0]=> string(69) "/xampp/htdocs/WORK.htaccess" [1]=> string(73) "/xampp/htdocs/WORKConverter.php" [2]=> string(69) "/xampp/htdocs/WORKEvent.php" [3]=> string(70) "/xampp/htdocs/WORKdefault_filter.json" [4]=> string(68) "/xampp/htdocs/WORKdefault_filter.xml" [5]=> string(80) "/xampp/htdocs/WORKCaching/ApcCache.php" [6]=> string(84) "/xampp/htdocs/WORKCaching/CacheFactory.php" } // Regex Call array(13) { [0]=> string(69) "/xampp/htdocs/WORKEvent.php" [1]=> string(73) "/xampp/htdocs/WORKConverter.php" [2]=> string(80) "/xampp/htdocs/WORKCaching/ApcCache.php" [3]=> string(84) "/xampp/htdocs/WORKCaching/CacheFactory.php" } 

Предложение Джеймса Кэмерона.

Это решение выполнило эту работу для меня. RecursiveIteratorIterator перечисляет все каталоги и файлы рекурсивно, но несортирован. Программа фильтрует список и сортирует его.

Я уверен, что есть способ написать это короче; не стесняйтесь улучшать его. Это всего лишь фрагмент кода. Возможно, вы захотите сутулиться в своих целях.

 <?php $path = '/pth/to/your/directories/and/files'; // an unsorted array of dirs & files $files_dirs = iterator_to_array( new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path),RecursiveIteratorIterator::SELF_FIRST) ); echo '<html><body><pre>'; // create a new associative multi-dimensional array with dirs as keys and their files $dirs_files = array(); foreach($files_dirs as $dir){ if(is_dir($dir) AND preg_match('/\/\.$/',$dir)){ $d = preg_replace('/\/\.$/','',$dir); $dirs_files[$d] = array(); foreach($files_dirs as $file){ if(is_file($file) AND $d == dirname($file)){ $f = basename($file); $dirs_files[$d][] = $f; } } } } //print_r($dirs_files); // sort dirs ksort($dirs_files); foreach($dirs_files as $dir => $files){ $c = substr_count($dir,'/'); echo str_pad(' ',$c,' ', STR_PAD_LEFT)."$dir\n"; // sort files asort($files); foreach($files as $file){ echo str_pad(' ',$c,' ', STR_PAD_LEFT)."|_$file\n"; } } echo '</pre></body></html>'; ?> 

Мое предложение без уродливых контрольных структур «foreach»

 $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)); $allFiles = array_filter(iterator_to_array($iterator), function($file) { return $file->isFile(); }); 

Вы можете только извлечь файл-путь, который вы можете сделать:

 array_keys($allFiles); 

Все еще 4 строки кода, но более прямолинейные, чем использование цикла или чего-то еще.

Вот измененная версия ответа Hors, работает немного лучше для моего случая, поскольку она удаляет базовый каталог, который передается по ходу, и имеет рекурсивный переключатель, который может быть установлен на false, что также удобно. Плюс, чтобы сделать вывод более читаемым, я разделил файлы и файлы подкаталогов, поэтому файлы сначала добавляются в файлы подкаталога (см. Результат, что я имею в виду).

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

 function get_filelist_as_array($dir, $recursive = true, $basedir = '') { if ($dir == '') {return array();} else {$results = array(); $subresults = array();} if (!is_dir($dir)) {$dir = dirname($dir);} // so a files path can be sent if ($basedir == '') {$basedir = realpath($dir).DIRECTORY_SEPARATOR;} $files = scandir($dir); foreach ($files as $key => $value){ if ( ($value != '.') && ($value != '..') ) { $path = realpath($dir.DIRECTORY_SEPARATOR.$value); if (is_dir($path)) { // do not combine with the next line or.. if ($recursive) { // ..non-recursive list will include subdirs $subdirresults = get_filelist_as_array($path,$recursive,$basedir); $results = array_merge($results,$subdirresults); } } else { // strip basedir and add to subarray to separate file list $subresults[] = str_replace($basedir,'',$path); } } } // merge the subarray to give the list of files then subdirectory files if (count($subresults) > 0) {$results = array_merge($subresults,$results);} return $results; } 

Я полагаю, что одна вещь должна быть осторожна с тем, чтобы не передавать значение $ basedir этой функции при ее вызове … в основном просто передать $ dir (или передать путь к файлу теперь тоже) и необязательно $ рекурсивный как false, если и как необходимо. Результат:

 [0] => demo-image.png [1] => filelist.php [2] => tile.png [3] => 2015\header.png [4] => 2015\08\background.jpg 

Наслаждайтесь! Хорошо, вернемся к программе, которую я использую в этом …

Это напечатает полный путь для всех файлов в данном каталоге, вы также можете передать другие функции обратного вызова в рекурсивный Dir.

 function printFunc($path){ echo $path."<br>"; } function recursiveDir($path, $fileFunc, $dirFunc){ $openDir = opendir($path); while (($file = readdir($openDir)) !== false) { $fullFilePath = realpath("$path/$file"); if ($file[0] != ".") { if (is_file($fullFilePath)){ if (is_callable($fileFunc)){ $fileFunc($fullFilePath); } } else { if (is_callable($dirFunc)){ $dirFunc($fullFilePath); } recursiveDir($fullFilePath, $fileFunc, $dirFunc); } } } } recursiveDir($dirToScan, 'printFunc', 'printFunc'); 

Вот мой:

 function recScan( $mainDir, $allData = array() ) { // hide files $hidefiles = array( ".", "..", ".htaccess", ".htpasswd", "index.php", "php.ini", "error_log" ) ; //start reading directory $dirContent = scandir( $mainDir ) ; foreach ( $dirContent as $key => $content ) { $path = $mainDir . '/' . $content ; // if is readable / file if ( ! in_array( $content, $hidefiles ) ) { if ( is_file( $path ) && is_readable( $path ) ) { $allData[] = $path ; } // if is readable / directory // Beware ! recursive scan eats ressources ! else if ( is_dir( $path ) && is_readable( $path ) ) { /*recursive*/ $allData = recScan( $path, $allData ) ; } } } return $allData ; } 

Вот что я придумал, и это не так много строк кода

 function show_files($start) { $contents = scandir($start); array_splice($contents, 0,2); echo "<ul>"; foreach ( $contents as $item ) { if ( is_dir("$start/$item") && (substr($item, 0,1) != '.') ) { echo "<li>$item</li>"; show_files("$start/$item"); } else { echo "<li>$item</li>"; } } echo "</ul>"; } show_files('./'); 

Он выводит что-то вроде

 ..idea .add.php .add_task.php .helpers .countries.php .mysqli_connect.php .sort.php .test.js .test.php .view_tasks.php 

** Точки – это точки неупорядоченного списка.

Надеюсь это поможет.

здесь у меня есть пример для этого

Список всех файлов и папок в каталоге csv (файл), который читается с помощью рекурсивной функции PHP

 <?php /** List all the files and folders in a Directory csv(file) read with PHP recursive function */ function getDirContents($dir, &$results = array()){ $files = scandir($dir); foreach($files as $key => $value){ $path = realpath($dir.DIRECTORY_SEPARATOR.$value); if(!is_dir($path)) { $results[] = $path; } else if($value != "." && $value != "..") { getDirContents($path, $results); //$results[] = $path; } } return $results; } $files = getDirContents('/xampp/htdocs/medifree/lab');//here folder name where your folders and it's csvfile; foreach($files as $file){ $csv_file =$file; $foldername = explode(DIRECTORY_SEPARATOR,$file); //using this get your folder name (explode your path); print_r($foldername); if (($handle = fopen($csv_file, "r")) !== FALSE) { fgetcsv($handle); while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { $num = count($data); for ($c=0; $c < $num; $c++) { $col[$c] = $data[$c]; } } fclose($handle); } } ?> 

http://myphpinformation.blogspot.in/2016/05/list-all-files-and-folders-in-directory-csv-file-read-with-php-recursive.html

Я улучшил с одной проверкой итерацию хороший код Hors Sujet, чтобы избежать включения папок в массив результатов:

 функция getDirContents ($ dir, & $ results = array ()) {

     $ files = scandir ($ dir);

     foreach ($ files as $ key => $ value) {
         $ path = realpath ($ dir.DIRECTORY_SEPARATOR. $ value);
         if (is_dir ($ path) == false) {
             $ results [] = $ path;
         }
         else if ($ value! = "." && $ value! = "..") {
             getDirContents ($ path, $ results);
             if (is_dir ($ path) == false) {
                 $ results [] = $ path;
             }   
         }
     }
     return $ results;

 }