使用 PHP glob 获取文件夹 - 无限级别的深度

Posted

技术标签:

【中文标题】使用 PHP glob 获取文件夹 - 无限级别的深度【英文标题】:Get folders with PHP glob - unlimited levels deep 【发布时间】:2011-08-11 18:55:29 【问题描述】:

我有这个查找文件夹并创建数组的工作函数。

function dua_get_files($path)

    foreach (glob($path . "/*", GLOB_ONLYDIR) as $filename)
    
        $dir_paths[] = $filename;   
    
    return $dir_paths;

这个函数只能找到当前位置的目录。我想找到子文件夹及其子文件夹中的目录路径等等。

数组应该仍然是目录路径的平面列表。

输出数组的外观示例

$dir_path[0] = 'path/folder1';
$dir_path[1] = 'path/folder1/child_folder1';
$dir_path[2] = 'path/folder1/child_folder2';
$dir_path[3] = 'path/folder2';
$dir_path[4] = 'path/folder2/child_folder1';
$dir_path[5] = 'path/folder2/child_folder2';
$dir_path[6] = 'path/folder2/child_folder3';

【问题讨论】:

【参考方案1】:

对于 PHP,如果您使用的是 linux/unix,您还可以在 unix find 命令中使用反引号(shell 执行)。文件系统上的目录搜索可能需要很长时间并出现循环——系统find 命令已经为速度和处理文件系统循环而构建。换句话说,与使用 php 本身搜索文件系统树相比,系统 exec 调用可能花费的 CPU 时间要少得多。

$dirs = `find $path -type d`;

记得清理 $path 输入,这样其他用户就不会传入安全性受损的路径名称(例如来自 url 或其他内容)。

将其放入数组中

$dirs = preg_split("/\s*\n+\s*/",`find $path -type d`,-1,PREG_SPLIT_NO_EMPTY);

【讨论】:

这个答案是跨版本、递归和允许权限的(前提是服务器没有以 root 身份运行 apache/php-fpm)。这甚至会在 PHP 3 上运行并产生正确的结果!您可以通过传入正确的参数来预先排序查找结果以首先查找。 unix find 客观上比 php 中的目录递归更快。【参考方案2】:

您可以使用 php GLOB 函数,但您必须创建一个递归函数以无限级别深度扫描目录。然后将结果存储在全局变量中。

function dua_get_files($path) 
    global $dir_paths; //global variable where to store the result
    foreach ($path as $dir)  //loop the input
        $dir_paths[] = $dir; //can use also "basename($dir)" or "realpath($dir)"
        $subdir =  glob($dir . DIRECTORY_SEPARATOR . '*', GLOB_ONLYDIR); //use DIRECTORY_SEPARATOR to be OS independent
        if (!empty($subdir))  //if subdir is not empty make function recursive
            dua_get_files($subdir); //execute the function again with current subdir
        
    


//usage:
$path = array('galleries'); //suport absolute or relative path. support one or multiple path
dua_get_files($path);
print('<pre>'.print_r($dir_paths,true).'</pre>'); //debug

【讨论】:

【参考方案3】:

很奇怪 - 每个人都建议递归,但最好只是循环:

$dir ='/dir';
while($dirs = glob($dir . '/*', GLOB_ONLYDIR)) 
  $dir .= '/*';
  if(!$result) 
     $result = $dirs;
    else 
      $result = array_merge($result, $dirs);
   

【讨论】:

不错!但是,当然,这绝对没有什么“非常奇怪”的地方:使用递归过程来迭代递归结构可能是最明显的事情。【参考方案4】:

如果你想递归处理目录,你应该看看RecursiveDirectoryIterator

$path = realpath('/etc');

$objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
foreach($objects as $name => $object)
    echo "$name\n";

【讨论】:

是的,这行得通。我编辑并添加了代码供其他人在您的答案中查看。 为什么选择 RecursiveDirectoryIterator 类?查看我的答案 @Davood 因为使用该迭代器,无需自己进行递归 ;-) ;; @Jens 您的编辑正在等待批准,需要再显示一张“批准投票”;如果没有很快获得批准,我会自己编辑,添加您发布的内容;谢谢! 不确定我是否真的明白你的意思;但是如果 PHP 提供了这样的类,为什么不使用它们呢? Heu...如果你的服务器没有 PHP >= 5.1.2 (已经超过几年了!),你有问题 ^^ PHP 5.2 (比 5.1 更早,尤其是 5.2.17) 本身已经到了生命的尽头......如果你认为你必须编写必须与 PHP (实际上,我不想待在你的位置)【参考方案5】:

使用这个功能:

function dua_get_files($path)

    $dir_paths = array();
    foreach (glob($path . "/*", GLOB_ONLYDIR) as $filename)
    
        $dir_paths[] = $filename;
        $a = glob("$filename/*", GLOB_ONLYDIR);
        if( is_array( $a ) )
        
            $b = dua_get_files( "$filename/*" );
            foreach( $b as $c )
            
                $dir_paths[] = $c;
            
        
    
    return $dir_paths;

【讨论】:

【参考方案6】:

试试这个:

function dua_get_files($path)

    $data = array();
    $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);

    foreach ($files as $file)
    
        if (is_dir($file) === true)
        
            $data[] = strval($file);
        
    

    return $data;

【讨论】:

@DennisMeissner:也不是公认的答案,但显然它可以完成工作。使用 glob 完成这项任务是无稽之谈。

以上是关于使用 PHP glob 获取文件夹 - 无限级别的深度的主要内容,如果未能解决你的问题,请参考以下文章

PHP使用glob()查找文件

PHP 获取给定目录的所有子目录

可以使 PHP 的 glob() 以不区分大小写的方式查找文件吗?

如何使用 os.walk 或 glob.glob 获取目录中所有类型的文件扩展名

如何在nodejs中获取文件夹大小,排除具有glob模式的某些路径?

python glob模块