在PHP中按日期排序文件

时间:2010-04-19 11:47:56

标签: php sorting

我目前有一个index.php文件,它允许我输出同一目录中的文件列表,输出显示名称然后我使用filemtime()函数来显示文件被修改的日期。我现在的问题是,如何对输出进行排序以显示最新修改的文​​件?我一直在考虑如何做到这一点。如果我只是用mysql交互来做这件事就没问题了。请给我一个例子,说明如何从最新修改的文​​件开始排序和输出文件列表。这就是我现在所拥有的

if ($handle = opendir('.')) {
while (false !== ($file = readdir($handle))) {
       if ($file != "." && $file != "..") {
        $lastModified = date('F d Y, H:i:s',filemtime($file));
          if(strlen($file)-strpos($file,".swf")== 4){
            echo "<tr><td><input type=\"checkbox\" name=\"box[]\"></td><td><a href=\"$file\" target=\"_blank\">$file</a></td><td>$lastModified</td></tr>";
           }
       }
   }
   closedir($handle);
}

5 个答案:

答案 0 :(得分:152)

这会将带有.swf扩展名的path / to / files中的所有文件放入一个数组中,然后按文件的mtime对该数组进行排序

$files = glob('path/to/files/*.swf');
usort($files, function($a, $b) {
    return filemtime($a) < filemtime($b);
});

以上使用Lambda function并需要PHP 5.3。在5.3之前,你会做

usort($files, create_function('$a,$b', 'return filemtime($a)<filemtime($b);'));

如果您不想使用匿名函数,您也可以将回调定义为常规函数,并将函数名称传递给usort

使用生成的数组,然后迭代这样的文件:

foreach($files as $file){
    printf('<tr><td><input type="checkbox" name="box[]"></td>
            <td><a href="%1$s" target="_blank">%1$s</a></td>
            <td>%2$s</td></tr>', 
            $file, // or basename($file) for just the filename w\out path
            date('F d Y, H:i:s', filemtime($file)));
}

请注意,因为您在对文件进行排序时已经调用filemtime,因此stat cache会在foreach循环中再次调用它时不会产生额外费用。

答案 1 :(得分:21)

您需要将文件放入数组中,以便对最后修改过的文件进行排序和查找。

$files = array();
if ($handle = opendir('.')) {
    while (false !== ($file = readdir($handle))) {
        if ($file != "." && $file != "..") {
           $files[filemtime($file)] = $file;
        }
    }
    closedir($handle);

    // sort
    ksort($files);
    // find the last modification
    $reallyLastModified = end($files);

    foreach($files as $file) {
        $lastModified = date('F d Y, H:i:s',filemtime($file));
        if(strlen($file)-strpos($file,".swf")== 4){
           if ($file == $reallyLastModified) {
             // do stuff for the real last modified file
           }
           echo "<tr><td><input type=\"checkbox\" name=\"box[]\"></td><td><a href=\"$file\" target=\"_blank\">$file</a></td><td>$lastModified</td></tr>";
        }
    }
}

未经测试,但这是怎么做的。

答案 2 :(得分:10)

使用RecursiveDirectoryIterator类的示例,它是在文件系统上递归迭代的便捷方式。

$output = array();
foreach( new RecursiveIteratorIterator( 
    new RecursiveDirectoryIterator( 'path', FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS ) ) as $value ) {      
        if ( $value->isFile() ) {
            $output[] = array( $value->getMTime(), $value->getRealPath() );
        }
}

usort ( $output, function( $a, $b ) {
    return $a[0] > $b[0];
});

答案 3 :(得分:0)

我使用您的确切建议代码只有几个额外的行。这个想法或多或少与@elias提出的想法相同,但在此解决方案中,密钥上不会发生冲突,因为目录中的每个文件都有不同的文件名,因此将其添加到密钥可以解决冲突。密钥的第一部分是日期时间字符串,其格式可以使我可以按字典顺序比较其中两个。

if ($handle = opendir('.')) {
    $result = array();
    while (false !== ($file = readdir($handle))) {
        if ($file != "." && $file != "..") {
            $lastModified = date('F d Y, H:i:s',filemtime($file));
            if(strlen($file)-strpos($file,".swf")== 4){
                $result [date('Y-m-d H:i:s',filemtime($file)).$file] =
                    "<tr><td><input type=\"checkbox\" name=\"box[]\"></td><td><a href=\"$file\" target=\"_blank\">$file</a></td><td>$lastModified</td></tr>";
            }
        }
    }
    closedir($handle);
    krsort($result);
    echo implode('', $result);
}

答案 4 :(得分:-1)

$files = array_diff(scandir($dir,SCANDIR_SORT_DESCENDING), array('..', '.'));
print_r($files);