Próbuję przejrzeć wszystkie pliki w katalogu, a jeśli istnieje katalog, przejrzeć wszystkie jego pliki i tak dalej, aż nie będzie już żadnych katalogów do przejścia. Każdy przetworzony element zostanie dodany do tablicy wyników w poniższej funkcji. To nie działa, chociaż nie jestem pewien, co mogę zrobić / co zrobiłem źle, ale przeglądarka działa niesamowicie wolno, gdy ten kod jest przetwarzany, każda pomoc jest mile widziana, dzięki!
Kod:
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'));
RecursiveDirectoryIterator
.
lub..
. Zobacz moją odpowiedź.Odpowiedzi:
Pobierz wszystkie pliki i foldery w katalogu, nie wywołuj funkcji, gdy masz
.
lub..
.Twój kod :
<?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'));
Wyjście (przykład):
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)
źródło
getDirContents($path, $results[$path]);
scandir()
nie wygląda na dobry pomysł, gdy wydajność jest krytyczna. Lepszą opcją jestRecursiveDirectoryIterator
( php.net/manual/en/class.recursivedirectoryiterator.php )realpath()
da docelową nazwę dowiązań symbolicznych w tym samym katalogu. Wypróbuj przykład na „/ usr / lib64” na komputerze z systemem Linux.$rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator('path/to/folder')); $files = array(); foreach ($rii as $file) { if ($file->isDir()){ continue; } $files[] = $file->getPathname(); } var_dump($files);
Spowoduje to wyświetlenie wszystkich plików ze ścieżkami.
źródło
if (!$file->isDir()) $files[] = $file->getPathname();
. Aby zapisać jedną linię.$Regex = new RegexIterator($rii, '/^.+\.php$/i', RecursiveRegexIterator::GET_MATCH);
.
i..
. Czy nadal nie musiałbyś ich odfiltrować?Jest to krótsza wersja:
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));
źródło
Pobierz wszystkie pliki z filtrem (drugi argument) i foldery w katalogu, nie wywołuj funkcji, jeśli masz
.
lub..
.Twój kod :
<?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$/'));
Wyjście (przykład):
// 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" }
Propozycja Jamesa Camerona.
źródło
Moja propozycja bez brzydkich "foreach" struktur sterujących jest taka
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)); $allFiles = array_filter(iterator_to_array($iterator), function($file) { return $file->isFile(); });
Możesz tylko wyodrębnić ścieżkę do pliku, co możesz zrobić:
array_keys($allFiles);
Nadal 4 linie kodu, ale prostsze niż użycie pętli lub czegoś podobnego.
źródło
CallbackFilterIterator
, który możesz później zapętlić:$allFilesIterator = new CallbackFilterIterator($iterator, function(SplFileInfo $fileInfo) { return $fileInfo->isFile(); });
Może to pomóc, jeśli chcesz pobrać zawartość katalogu jako tablicę, ignorując ukryte pliki i katalogi.
function dir_tree($dir_path) { $rdi = new \RecursiveDirectoryIterator($dir_path); $rii = new \RecursiveIteratorIterator($rdi); $tree = []; foreach ($rii as $splFileInfo) { $file_name = $splFileInfo->getFilename(); // Skip hidden files and directories. if ($file_name[0] === '.') { continue; } $path = $splFileInfo->isDir() ? array($file_name => array()) : array($file_name); for ($depth = $rii->getDepth() - 1; $depth >= 0; $depth--) { $path = array($rii->getSubIterator($depth)->current()->getFilename() => $path); } $tree = array_merge_recursive($tree, $path); } return $tree; }
Wynik byłby podobny;
dir_tree(__DIR__.'/public'); [ 'css' => [ 'style.css', 'style.min.css', ], 'js' => [ 'script.js', 'script.min.js', ], 'favicon.ico', ]
Źródło
źródło
Oto, co wymyśliłem, a to jest z niewielką ilością linii kodu
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('./');
Wyprowadza coś takiego
** Kropki to kropki nieuporządkowanej listy.
Mam nadzieję że to pomoże.
źródło
Oto zmodyfikowana wersja odpowiedzi Hors, działa nieco lepiej w moim przypadku, ponieważ usuwa katalog podstawowy, który jest przekazywany na bieżąco, i ma przełącznik rekurencyjny, który można ustawić na fałsz, co jest również przydatne. Dodatkowo, aby dane wyjściowe były bardziej czytelne, oddzieliłem pliki i podkatalogi, więc pliki są dodawane najpierw, a następnie pliki podkatalogów (patrz wynik, o co mi chodzi.)
Wypróbowałem kilka innych metod i sugestii i na tym właśnie skończyłem. Miałem już inną metodę pracy, która była bardzo podobna, ale wydawała się nieskuteczna tam, gdzie był podkatalog bez plików, ale ten podkatalog miał podkatalog z plikami, nie skanował podkatalogu w poszukiwaniu plików - więc niektóre odpowiedzi mogą wymagać przetestowania w tym przypadku.) ... w każdym razie pomyślałem, że opublikuję tutaj moją wersję na wypadek, gdyby ktoś szukał ...
function get_filelist_as_array($dir, $recursive = true, $basedir = '', $include_dirs = false) { 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)) { // optionally include directories in file list if ($include_dirs) {$subresults[] = str_replace($basedir, '', $path);} // optionally get file list for all subdirectories if ($recursive) { $subdirresults = get_filelist_as_array($path, $recursive, $basedir, $include_dirs); $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; }
Przypuszczam, że należy uważać na to, aby nie przekazywać wartości opartej na $ do tej funkcji podczas jej wywoływania ... przeważnie po prostu przekaż $ dir (lub przekazanie ścieżki pliku też będzie działać teraz) i opcjonalnie $ rekurencyjne jako fałsz, jeśli i jak potrzebne. Wynik:
Cieszyć się! OK, wracając do programu, którego używam w ...
AKTUALIZACJA Dodano dodatkowy argument za włączaniem katalogów do listy plików lub nie (zapamiętanie innych argumentów będzie musiało zostać przekazane, aby użyć tego).
$results = get_filelist_as_array($dir, true, '', true);
źródło
To rozwiązanie zadziałało za mnie. RecursiveIteratorIterator wyświetla wszystkie katalogi i pliki rekurencyjnie, ale nieposortowane. Program filtruje listę i sortuje ją.
Jestem pewien, że istnieje sposób na napisanie tego krótszego; nie krępuj się go ulepszyć. To tylko fragment kodu. Możesz go odpicować do swoich celów.
<?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>'; ?>
źródło
Rozwiązanie @ A-312 może powodować problemy z pamięcią, ponieważ może utworzyć ogromną tablicę, jeśli
/xampp/htdocs/WORK
zawiera dużo plików i folderów.Jeśli masz PHP 7, możesz użyć Generatorów i zoptymalizować pamięć PHP w następujący sposób:
function getDirContents($dir) { $files = scandir($dir); foreach($files as $key => $value){ $path = realpath($dir.DIRECTORY_SEPARATOR.$value); if(!is_dir($path)) { yield $path; } else if($value != "." && $value != "..") { yield from getDirContents($path); yield $path; } } } foreach(getDirContents('/xampp/htdocs/WORK') as $value) { echo $value."\n"; }
wydajność z
źródło
Spowoduje to wyświetlenie pełnej ścieżki wszystkich plików w podanym katalogu, możesz również przekazać inne funkcje zwrotne do recursiveDir.
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');
źródło
realpath("$path/$file");
To jest mała modyfikacja odpowiedzi Majicka .
Właśnie zmieniłem strukturę tablicy zwracaną przez funkcję.
Od:
array() => { [0] => "test/test.txt" }
Do:
array() => { 'test/test.txt' => "test.txt" }
/** * @param string $dir * @param bool $recursive * @param string $basedir * * @return array */ function getFileListAsArray(string $dir, bool $recursive = true, string $basedir = ''): array { 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 = self::getFileListAsArray($path, $recursive, $basedir); $results = array_merge($results, $subdirresults); } } else { // strip basedir and add to subarray to separate file list $subresults[str_replace($basedir, '', $path)] = $value; } } } // merge the subarray to give the list of files then subdirectory files if (count($subresults) > 0) { $results = array_merge($subresults, $results); } return $results; }
Może pomóc tym, którzy mają dokładnie takie same oczekiwane rezultaty jak ja.
źródło
Do kogo potrzebne są najpierw pliki niż foldery (starsze alfabetycznie).
Może korzystać z następującej funkcji. To nie jest funkcja automatycznego wywoływania. Będziesz mieć listę katalogów, widok katalogów, listę plików i listę folderów jako oddzielną tablicę.
Spędzam na to dwa dni i nie chcę, żeby ktoś marnował na to też czas, nadzieja komuś pomaga.
function dirlist($dir){ if(!file_exists($dir)){ return $dir.' does not exists'; } $list = array('path' => $dir, 'dirview' => array(), 'dirlist' => array(), 'files' => array(), 'folders' => array()); $dirs = array($dir); while(null !== ($dir = array_pop($dirs))){ if($dh = opendir($dir)){ while(false !== ($file = readdir($dh))){ if($file == '.' || $file == '..') continue; $path = $dir.DIRECTORY_SEPARATOR.$file; $list['dirlist_natural'][] = $path; if(is_dir($path)){ $list['dirview'][$dir]['folders'][] = $path; // Bos klasorler while icerisine tekrar girmeyecektir. Klasorun oldugundan emin olalım. if(!isset($list['dirview'][$path])){ $list['dirview'][$path] = array(); } $dirs[] = $path; //if($path == 'D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-content\upgrade'){ press($path); press($list['dirview']); die; } } else{ $list['dirview'][$dir]['files'][] = $path; } } closedir($dh); } } // if(!empty($dirlist['dirlist_natural'])) sort($dirlist['dirlist_natural'], SORT_LOCALE_STRING); // delete safe ama gerek kalmadı. if(!empty($list['dirview'])) ksort($list['dirview']); // Dosyaları dogru sıralama yaptırıyoruz. Deniz P. - info[at]netinial.com foreach($list['dirview'] as $path => $file){ if(isset($file['files'])){ $list['dirlist'][] = $path; $list['files'] = array_merge($list['files'], $file['files']); $list['dirlist'] = array_merge($list['dirlist'], $file['files']); } // Add empty folders to the list if(is_dir($path) && array_search($path, $list['dirlist']) === false){ $list['dirlist'][] = $path; } if(isset($file['folders'])){ $list['folders'] = array_merge($list['folders'], $file['folders']); } } //press(array_diff($list['dirlist_natural'], $list['dirlist'])); press($list['dirview']); die; return $list; }
wyświetli coś takiego.
[D:\Xampp\htdocs\exclusiveyachtcharter.localhost] => Array ( [files] => Array ( [0] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\.htaccess [1] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\index.php [2] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\license.txt [3] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\php.php [4] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\readme.html [5] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-activate.php [6] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-blog-header.php [7] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-comments-post.php [8] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-config-sample.php [9] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-config.php [10] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-cron.php [11] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-links-opml.php [12] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-load.php [13] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-login.php [14] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-mail.php [15] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-settings.php [16] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-signup.php [17] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-trackback.php [18] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\xmlrpc.php ) [folders] => Array ( [0] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\exclusiv_excluwlsql [1] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-admin [2] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-content [3] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-includes ) )
wyjście dirview
[dirview] => Array ( [0] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\.htaccess [1] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\index.php [2] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\license.txt [3] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\php.php [4] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\readme.html [5] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-activate.php [6] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-blog-header.php [7] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-comments-post.php [8] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-config-sample.php [9] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-config.php [10] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-cron.php [11] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-links-opml.php [12] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-load.php [13] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-login.php [14] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-mail.php [15] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-settings.php [16] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-signup.php [17] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-trackback.php [18] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\xmlrpc.php [19] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost [20] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\exclusiv_excluwlsql\exclusiv_excluwl.sql [21] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\exclusiv_excluwlsql\exclusiv_excluwl.sql.zip [22] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\exclusiv_excluwlsql )
źródło
Dodaj opcję ścieżki względnej:
function getDirContents($dir, $relativePath = false) { $fileList = array(); $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)); foreach ($iterator as $file) { if ($file->isDir()) continue; $path = $file->getPathname(); if ($relativePath) { $path = str_replace($dir, '', $path); $path = ltrim($path, '/\\'); } $fileList[] = $path; } return $fileList; } print_r(getDirContents('/path/to/dir')); print_r(getDirContents('/path/to/dir', true));
Wynik:
Array ( [0] => /path/to/dir/test1.html [1] => /path/to/dir/test.html [2] => /path/to/dir/index.php ) Array ( [0] => test1.html [1] => test.html [2] => index.php )
źródło
Tutaj jest moje :
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 ; }
źródło
tutaj mam na to przykład
Wyświetl wszystkie pliki i foldery w katalogu csv (plik) odczytywanym za pomocą funkcji rekurencyjnej 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
źródło
Poprawiłem za pomocą jednej iteracji sprawdzania dobry kod Hors Sujet, aby uniknąć włączania folderów do tablicy wyników:
źródło
Gotowy do kopiowania i wklejania dla typowych zastosowań, ulepszona / rozszerzona wersja jednej odpowiedzi powyżej :
function getDirContents(string $dir, int $onlyFiles = 0, string $excludeRegex = '~/\.git/~', int $maxDepth = -1): array { $results = []; $scanAll = scandir($dir); sort($scanAll); $scanDirs = []; $scanFiles = []; foreach($scanAll as $fName){ if ($fName === '.' || $fName === '..') { continue; } $fPath = str_replace(DIRECTORY_SEPARATOR, '/', realpath($dir . '/' . $fName)); if (strlen($excludeRegex) > 0 && preg_match($excludeRegex, $fPath . (is_dir($fPath) ? '/' : ''))) { continue; } if (is_dir($fPath)) { $scanDirs[] = $fPath; } elseif ($onlyFiles >= 0) { $scanFiles[] = $fPath; } } foreach ($scanDirs as $pDir) { if ($onlyFiles <= 0) { $results[] = $pDir; } if ($maxDepth !== 0) { foreach (getDirContents($pDir, $onlyFiles, $excludeRegex, $maxDepth - 1) as $p) { $results[] = $p; } } } foreach ($scanFiles as $p) { $results[] = $p; } return $results; }
A jeśli potrzebujesz ścieżek względnych:
function updateKeysWithRelPath(array $paths, string $baseDir, bool $allowBaseDirPath = false): array { $results = []; $regex = '~^' . preg_quote(str_replace(DIRECTORY_SEPARATOR, '/', realpath($baseDir)), '~') . '(?:/|$)~s'; $regex = preg_replace('~/~', '/(?:(?!\.\.?/)(?:(?!/).)+/\.\.(?:/|$))?(?:\.(?:/|$))*', $regex); // limited to only one "/xx/../" expr if (DIRECTORY_SEPARATOR === '\\') { $regex = preg_replace('~/~', '[/\\\\\\\\]', $regex) . 'i'; } foreach ($paths as $p) { $rel = preg_replace($regex, '', $p, 1); if ($rel === $p) { throw new \Exception('Path relativize failed, path "' . $p . '" is not within basedir "' . $baseDir . '".'); } elseif ($rel === '') { if (!$allowBaseDirPath) { throw new \Exception('Path relativize failed, basedir path "' . $p . '" not allowed.'); } else { $results[$rel] = './'; } } else { $results[$rel] = $p; } } return $results; } function getDirContentsWithRelKeys(string $dir, int $onlyFiles = 0, string $excludeRegex = '~/\.git/~', int $maxDepth = -1): array { return updateKeysWithRelPath(getDirContents($dir, $onlyFiles, $excludeRegex, $maxDepth), $dir); }
Ta wersja rozwiązuje / ulepsza:
realpath
gdy PHPopen_basedir
nie obejmuje..
katalogu.Przykłady:
// list only `*.php` files and skip .git/ and the current file $onlyPhpFilesExcludeRegex = '~/\.git/|(?<!/|\.php)$|^' . preg_quote(str_replace(DIRECTORY_SEPARATOR, '/', realpath(__FILE__)), '~') . '$~is'; $phpFiles = getDirContents(__DIR__, 1, $onlyPhpFilesExcludeRegex); print_r($phpFiles); // with relative keys $phpFiles = getDirContentsWithRelKeys(__DIR__, 1, $onlyPhpFilesExcludeRegex); print_r($phpFiles); // with "include only" regex to include only .html and .txt files with "/*_mails/en/*.(html|txt)" path '~/\.git/|^(?!.*/(|' . '[^/]+_mails/en/[^/]+\.(?:html|txt)' . ')$)~is'
źródło