8
$dir = '/master/files';
$files = scandir($dir);
foreach($files as $file){
   if(($file != '.') && ($file != '..')){
      if(is_dir($dir.'/'.$file)){
         echo '<li class="folder">'.$file.'</li>';
      }else{
         echo '<li class="file">'.$file.'</li>';
      }
   }
}

从上面的脚本,我得到结果:

images (folder)
index.html    
javascript (folder)
style.css

如何先对文件夹排序,再对文件排序?

4

7 回答 7

9

试试这个 :

$dir = '/master/files';
$directories = array();
$files_list  = array();
$files = scandir($dir);
foreach($files as $file){
   if(($file != '.') && ($file != '..')){
      if(is_dir($dir.'/'.$file)){
         $directories[]  = $file;

      }else{
         $files_list[]    = $file;

      }
   }
}

foreach($directories as $directory){
   echo '<li class="folder">'.$directory.'</li>';
}
foreach($files_list as $file_list){
   echo '<li class="file">'.$file_list.'</li>';
}
于 2013-02-25T05:07:37.523 回答
4

你不需要做 2 个循环,你可以用这段代码来完成这项工作:

<?php

function scandirSorted($path) {

    $sortedData = array();
    foreach(scandir($path) as $file) {

        // Skip the . and .. folder
        if($file == '.' || $file == '..')
            continue;            

        if(is_file($path . $file)) {
            // Add entry at the end of the array
            array_push($sortedData, '<li class="folder">' . $file . '</li>');
        } else {
            // Add entry at the begin of the array
            array_unshift($sortedData, '<li class="file">' . $file . '</li>');
        }
    }
    return $sortedData;
}

?>

此函数将返回您的路径条目列表,首先是文件夹,然后是文件。

于 2013-02-25T05:07:23.310 回答
3

尽可能少地修改你的代码:

$folder_list = "";
$file_list = "";
$dir = '/master/files';
$files = scandir($dir);
foreach($files as $file){
   if(($file != '.') && ($file != '..')){
      if(is_dir($dir.'/'.$file)){
         $folder_list .= '<li class="folder">'.$file.'</li>';
      }else{
         $file_list .= '<li class="file">'.$file.'</li>';
      }
   }
}

print $folder_list;
print $file_list;

这只循环遍历所有内容一次,而不需要多次遍历。

于 2013-02-25T05:08:20.960 回答
2

我有一个 N 深度递归目录扫描的解决方案:

function scanRecursively($dir = "/") {
    $scan = array_diff(scandir($dir), array('.', '..'));
    $tree = array();
    $queue = array();
    foreach ( $scan as $item ) 
        if ( is_file($item) ) $queue[] = $item;
        else $tree[] = scanRecursively($dir . '/' . $item);
    return array_merge($tree, $queue);
}
于 2014-01-12T10:26:05.200 回答
1

将输出存储在 2 个数组中,然后遍历数组以正确的顺序输出它们。

$dir = '/master/files';

$contents = scandir($dir);

// create blank arrays to store folders and files
$folders = $files = array();

foreach ($contents as $file) {

    if (($file != '.') && ($file != '..')) {

        if (is_dir($dir.'/'.$file)) {

            // add to folders array
            $folders[] = $file;

        } else {

            // add to files array
            $files[] = $file;

        }
    }
}

// output folders
foreach ($folders as $folder) {

    echo '<li class="folder">' . $folder . '</li>';

}

// output files
foreach ($files as $file) {

    echo '<li class="file">' . $file . '</li>';

}
于 2013-02-25T05:09:03.060 回答
1

作为 CodeIgniter 的爱好者,我实际上已经修改了核心directory_helper,使其除了设置深度和选择是否应包含隐藏文件之外,还包括使某些文件免于扫描的能力。

所有功劳归于 CI 的原作者。我只是用豁免数组添加到它并在排序中构建。

它使用 ksort 对文件夹进行排序,因为文件夹名称被设置为键,而 natsort 对每个文件夹中的文件进行排序。

您可能需要做的唯一一件事就是为您的环境定义 DIRECTORY_SEPARATOR 是什么,但我认为您不需要修改太多其他内容。

function directory_map($source_dir, $directory_depth = 0, $hidden = FALSE, $exempt = array())
{
    if ($fp = @opendir($source_dir))
    {
        $folddata   = array();
        $filedata   = array();
        $new_depth  = $directory_depth - 1;
        $source_dir = rtrim($source_dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;

        while (FALSE !== ($file = readdir($fp)))
        {
            // Remove '.', '..', and hidden files [optional]
            if ($file === '.' OR $file === '..' OR ($hidden === FALSE && $file[0] === '.'))
            {
                continue;
            }

            is_dir($source_dir.$file) && $file .= DIRECTORY_SEPARATOR;

            if (($directory_depth < 1 OR $new_depth > 0) && is_dir($source_dir.$file))
            {
                $folddata[$file] = directory_map($source_dir.$file, $new_depth, $hidden, $exempt);

            }
            elseif(empty($exempt) || !empty($exempt) && !in_array($file, $exempt))
            {
                $filedata[] = $file;
            }
        }

        !empty($folddata) ? ksort($folddata) : false;
        !empty($filedata) ? natsort($filedata) : false;

        closedir($fp);
        return array_merge($folddata, $filedata);
    }

    return FALSE;
}

使用示例是:

$filelist = directory_map('full_server_path');

如上所述,它将文件夹名称设置为子数组的键,因此您可以期待以下内容:

Array(
[documents/] => Array(
    [0] => 'document_a.pdf',
    [1] => 'document_b.pdf'    
    ),
[images/] => Array(
    [tn/] = Array(
        [0] => 'picture_a.jpg',
        [1] => 'picture_b.jpg'
        ),
    [0] => 'picture_a.jpg',
    [1] => 'picture_b.jpg'        
    ),
[0] => 'file_a.jpg',
[1] => 'file_b.jpg'
);

请记住,豁免将应用于所有文件夹。如果您想跳过 index.html 文件或您不想包含的目录中使用的其他文件,这很方便。

于 2017-05-29T16:03:57.017 回答
0

尝试

<?php
    $path = $_SERVER['DOCUMENT_ROOT'];
    chdir ($path);

    $dir = array_diff (scandir ('.'), array ('.', '..', '.DS_Store', 'Thumbs.db'));

    usort ($dir, create_function ('$a,$b', '
        return  is_dir ($a)
        ? (is_dir ($b) ? strnatcasecmp ($a, $b) : -1)
        : (is_dir ($b) ? 1 : (
            strcasecmp (pathinfo ($a, PATHINFO_EXTENSION), pathinfo ($b, PATHINFO_EXTENSION)) == 0
            ? strnatcasecmp ($a, $b)
            : strcasecmp (pathinfo ($a, PATHINFO_EXTENSION), pathinfo ($b, PATHINFO_EXTENSION))
        ))
    ;
'));

    header ('content-type: text/plain');
    print_r ($dir);
?>
于 2013-02-25T05:10:20.863 回答