在 PHP 中按日期对文件进行排序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2667065/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 07:16:27  来源:igfitidea点击:

sort files by date in PHP

phpsorting

提问by sasori

I currently have an index.php file which allows me to output the list of files inside the same directory, the output shows the names then I used filemtime() function to show the date when the file was modified. my problem now is, how will I sort the output to show the latest modified file ?, I've been thinking for awhile how to do this. if only I am doing it with mysql interaction there will be no problem at all. please show me an example how to sort and output the list of files starting from the latest modified one. this is what i have for now

我目前有一个 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);
}

采纳答案by elias

You need to put the files into an array in order to sort and find the last modified file.

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

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

Not tested, but that's how to do it.

未经测试,但这是如何做到的。

回答by Gordon

This would get all files in path/to/files with an .swf extension into an array and then sort that array by the file's mtime

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

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

The above uses an Lambda functionand requires PHP 5.3. Prior to 5.3, you would do

以上使用了一个Lambda 函数,需要 PHP 5.3。在 5.3 之前,你会做

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

If you don't want to use an anonymous function, you can just as well define the callback as a regular function and pass the function name to usortinstead.

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

With the resulting array, you would then iterate over the files like this:

使用结果数组,您可以像这样迭代文件:

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

Note that because you already called filemtimewhen sorting the files, there is no additional cost when calling it again in the foreach loop due to the stat cache.

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

回答by Danijel

An example that uses RecursiveDirectoryIteratorclass, it's a convenient way to iterate recursively over filesystem.

一个使用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];
});

回答by Wynn

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

回答by Roberto Trani

I use your exact proposed code with only some few additional lines. The idea is more or less the same of the one proposed by @elias, but in this solution there cannot be conflicts on the keys since each file in the directory has a different filename and so adding it to the key solves the conflicts. The first part of the key is the datetime string formatted in a manner such that I can lexicographically compare two of them.

我使用您提出的确切代码,仅添加了几行。这个想法或多或少与@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);
}