PHP scandir结果:按文件夹-文件排序,然后按字母顺序排序

6

scandir 的 PHP 手册: 默认情况下,排序顺序为按字母升序排列

我正在构建一个文件浏览器(在 Windows 上),因此我希望返回的地址按文件夹/文件排序,然后按这些子集按字母表顺序排序。

例如:现在,我扫描并输出

Aardvark.txt
BarDir
BazDir
Dante.pdf
FooDir

and I want

BarDir
BazDir
FooDir
Aardvark.txt
Dante.pdf

除了我自己可以想出来的 usortis_dir() 解决方案之外,还有没有快速高效的方法来做到这一点?
写了 这条评论的忍者是走在正轨上了 - 那是最好的方式吗?

发布你自己找出来的内容,然后我们可以告诉你是否可以改进。 - alex
@alex - 如果有更高效的方法我不想浪费时间自己去研究,如果没有更好的答案,我可以从手册中复制一些内容。 - Ben
我的解决方案已经被编辑了 - 你可能想要编辑你的问题以反映这一点。 - alex
3个回答

5

这能满足您的需求吗?

function readDir($path) {

    // Make sure we have a trailing slash and asterix
    $path = rtrim($path, '/') . '/*';

    $dirs = glob($path, GLOB_ONLYDIR);

    $files = glob($path);

    return array_unique(array_merge($dirs, $files));

}

$path = '/path/to/dir/';

readDir($path);

请注意,您不能使用glob('*.*')来获取文件,因为它会选择名为like.this的文件夹。

@alex - 是的,那是一个相当优雅的解决方案。你认为它与 usort 相比如何? - Ben
@Steve 只要你的文件系统按照你想要的顺序返回它们,那么速度会更快。我实际上没有做任何排序。这对你有用吗? 编辑 进行了一些编辑。让我知道它是否对你有用(在我的测试中有效)。 - alex
@alex - 进行了一些微调,现在正在完成。例如,$filepath ='path/to/dir/*'; 当正常工作后,会更新问题并提供最终代码。 - Ben
2
@Steve 我想你是指 glob。Blob 什么也不做。(虽然它应该做点什么。) - Jeff Davis
@Steve 它的工作方式不同,因为我可以将我的文件夹命名为 something.something(并且它通过 *.* 返回)。你会在你的数组中得到两次那个文件夹。 :) - alex
显示剩余4条评论

4
请尝试这个。一个简单的函数,用于按文件和文件夹(目录)对PHP scandir结果进行排序:
function sort_dir_files($dir)
{
        $sortedData = array();
        foreach(scandir($dir) as $file)
        {
                if(is_file($dir.'/'.$file))
                        array_push($sortedData, $file);
                else
                        array_unshift($sortedData, $file);
        }
        return $sortedData;
}

比上面的解决方案更好,因为上面的解决方案“在我的电脑上无法工作” :-). - Bram Janssens

0
我来晚了,但我想提供我的解决方案,使用readdir()而不是glob()。我从解决方案中缺少的是你的解决方案的递归版本。但是使用readdir比使用glob更快。
因此,使用glob会像这样:
function myglobdir($path, $level = 0) {
    $dirs   = glob($path.'/*', GLOB_ONLYDIR);
    $files  = glob($path.'/*');
    $all2   = array_unique(array_merge($dirs, $files));
    $filter = array($path.'/Thumbs.db');
    $all    = array_diff($all2,$filter);

    foreach ($all as $target){
        echo "$target<br />";
        if(is_dir("$target")){
            myglobdir($target, ($level+1));
        }
    }
}

这个例子使用readdir函数,但输出基本相同:

function myreaddir($target, $level = 0){
    $ignore = array("cgi-bin", ".", "..", "Thumbs.db");
    $dirs = array();
    $files = array();

    if(is_dir($target)){
        if($dir = opendir($target)){
            while (($file = readdir($dir)) !== false){
                if(!in_array($file, $ignore)){
                    if(is_dir("$target/$file")){
                        array_push($dirs, "$target/$file");
                    }
                    else{
                        array_push($files, "$target/$file");
                    }

                }
            }

            //Sort
            sort($dirs);
            sort($files);
            $all = array_unique(array_merge($dirs, $files));

            foreach ($all as $value){
                echo "$value<br />";
                if(is_dir($value)){
                    myreaddir($value, ($level+1));
                }
            }
        }
        closedir($dir);
    }

}

我希望有人会发现这个有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接