List all the files and folders in a Directory with PHP recursive function

我试图遍历一个目录中的所有文件,如果有一个目录,就遍历它的所有文件,如此循环,直到没有更多的目录可以访问。每个处理过的项目都将添加到下面函数中的结果数组中。它不工作,虽然我不知道我能做什么/我做错了什么,但浏览器运行速度慢得可怕,当下面的代码处理,任何帮助是感谢,谢谢!

密码:

    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'));
201471 次浏览
$rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator('path/to/folder'));


$files = array();


foreach ($rii as $file) {


if ($file->isDir()){
continue;
}


$files[] = $file->getPathname();


}






var_dump($files);

这将为您带来所有带有路径的文件。

获取一个目录中的所有文件和文件夹,当有 ...时不要调用函数。

你的代码:

<?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)

这是 Hors 的一个修改版本,对我的情况稍微好一点,因为它去掉了传递的基本目录,并且有一个可以设置为 false 的递归开关,这也很方便。另外,为了使输出更具可读性,我将文件和子目录文件分开,因此首先添加这些文件,然后再添加子目录文件(请参见我的意思的结果)

我尝试了一些其他的方法和建议,这就是我的结果。我已经有了另一个非常相似的工作方法,但似乎失败了,有一个子目录没有文件,但该子目录有一个子目录 文件,它没有扫描子目录的文件-所以一些答案可能需要测试的情况下不管怎样,我觉得我应该把我的版本也贴在这里,以防有人看到..。

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;
}

我认为在调用这个函数时要注意不要传递 $basedir 值给它... ... 大多数情况下只传递 $dir (或者传递一个文件路径现在也可以工作) ,如果需要的话,还可以选择传递 $resive 作为 false。结果是:

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

好好享受吧,好了,回到我正在用的程序。

UPDATE 为在文件列表中包含或不包含目录添加了额外的参数(记住,要使用这个参数还需要传递其他参数)例如。

$results = get_filelist_as_array($dir, true, '', true);

这将打印给定目录中所有文件的完整路径,您还可以将其他回调函数传递给 cursiveDir。

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');

Get all the files with filter (2nd argument) and folders in a directory, don't call function when you have . or ...

你的代码:

<?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"
}

詹姆斯 · 卡梅隆的提议。

这个函数用于获取 递归迭代器目录中的所有文件和文件夹。

参见构造文档: https://www.php.net/manual/en/recursiveiteratoriterator.construct.php

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));

这个解决方案帮了我大忙。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>';


?>

这是我的:

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 ;
}

Here is what I came up with and this is with not much lines of code

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

这些点是无序列表中的点。

希望这个能帮上忙。

这里我有一个例子

列出使用 PHP 递归函数读取的目录 csv (文件)中的所有文件和文件夹

<?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 的优秀代码,以避免在结果数组中包含文件夹:

function 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;


}

我的建议没有丑陋的“ foreach”控制结构

$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));
$allFiles = array_filter(iterator_to_array($iterator), fn($file) $file->isFile());

您可能只想提取文件路径,您可以通过以下方式实现:

array_keys($allFiles);

仍然是4行代码,但比使用循环之类的更直接。

这是对 马吉克答案的一点修改。
我只是改变了函数返回的数组结构。

来自:

array() => {
[0] => "test/test.txt"
}

致:

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;
}

也许能帮助那些和我有相同预期结果的人。

谁需要列表文件首先比文件夹(字母较老)。

Can use following function. This is not self calling function. So you will have directory list, directory view, files 列表和文件夹列表也作为独立的数组。

我花了两天的时间,不希望有人会浪费他的时间这也,希望帮助别人。

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;
}

会输出这样的东西。

[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
)


)

Didiview 输出

    [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
)

可以复制和粘贴常见用例的功能,改进/扩展版本的 one answer above:

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;
}

如果你需要相对路径:

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);
}

这个版本解决/改进了:

  1. 当 PHP open_basedir不覆盖 ..目录时,来自 realpath的警告。
  2. 不对结果数组使用引用
  3. 允许排除目录和文件
  4. 只允许列出文件/目录
  5. 允许限制搜索深度
  6. 它总是首先使用目录对输出进行排序(因此可以按相反的顺序删除/清空目录)
  7. 允许获取具有相对键的路径
  8. 重型优化的数十万甚至数百万文件
  9. 在评论中写更多:)

例子:

// 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'

This could help if you wish to get directory contents as an array, ignoring hidden files and directories.

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;
}

结果会是这样的:

dir_tree(__DIR__.'/public');


[
'css' => [
'style.css',
'style.min.css',
],
'js' => [
'script.js',
'script.min.js',
],
'favicon.ico',
]

来源

添加相对路径选项:

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));

产出:

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
)

@ A-312的解决方案可能会导致内存问题,因为如果 /xampp/htdocs/WORK包含大量文件和文件夹,它可能会创建一个巨大的数组。

如果你有 PHP7,那么你可以使用 Generators并像这样优化 PHP 的内存:

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";
}

从... 屈服

如果使用 Laravel,可以使用 Storage facade 上的 getAllFiles方法递归地获取所有文件,如下面的文档所示: https://laravel.com/docs/8.x/filesystem#get-all-files-within-a-directory

use Illuminate\Support\Facades\Storage;


class TestClass {


public function test() {
// Gets all the files in the 'storage/app' directory.
$files = Storage::getAllFiles(storage_path('app'))
}


}


我发现了这个简单的代码: https://stackoverflow.com/a/24981012

 $Directory = new RecursiveDirectoryIterator($path);
$Iterator = new RecursiveIteratorIterator($Directory);
//Filter to get only PDF, JPEG, JPG, GIF, TIF files.
$Regex = new RegexIterator($Iterator, '/^.+(.jpe?g|.gif|.png|.tif|.pdf)$/i', RecursiveRegexIterator::GET_MATCH);


foreach($Regex as $val => $Regex){
echo "$val\n<br>";
}