如何在PHP中按日期排序文件

ckocjqey  于 5个月前  发布在  PHP
关注(0)|答案(6)|浏览(79)

我目前有一个脚本,它允许我输出同一目录内的文件列表。
输出显示名称,然后我使用filemtime()函数显示文件被修改的日期。
我将如何排序输出以显示最新修改的文件?
这就是我现在所拥有的:

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 "$file - $lastModified";
            }
        }
    }
    closedir($handle);
}

字符串

vfhzx4xs

vfhzx4xs1#

这将把路径/to/files中扩展名为.swf的所有文件放到一个数组中,然后按文件的mtime对该数组进行排序

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

字符串
上面的代码使用Lambda function,需要PHP 5.3。

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


如果你不想使用匿名函数,你也可以将回调定义为一个常规函数,并将函数名传递给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,所以在foreach循环中再次调用stat cache时不会产生额外的开销。

cyej8jka

cyej8jka2#

您需要将文件放入数组中,以便排序并找到最后修改的文件。

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

字符串
没有测试过,但这就是如何做到这一点。

1sbrub3j

1sbrub3j3#

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

字符串

w8rqjzmb

w8rqjzmb4#

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

字符串

xoefb8l8

xoefb8l85#

我使用了你提出的代码,只增加了几行,这个想法或多或少和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);
}

字符串

llycmphe

llycmphe6#

对于那些拼命关注微优化性能(最小化迭代函数调用的总数)的人来说,可以将文件修改时间存储为行数组的第一个元素,将文件名存储为第二个元素。
一旦设置好了,你可以简单地调用sort(),算法将首先通过mod时间进行比较,然后使用唯一的文件名打破平局。
产品编号:(Demo

$result = [];
foreach (glob('path/to/files/*.swf') as $file) {
    $result[] = [filemtime($file), $file];
}
sort($result);
var_export($result);

字符串

  • 备注:如果你不想在文件名前加上路径($file),那么在调用glob()之前使用chdir('path/to/files')移动到目标目录。

当然,使用标准的sort()意味着你被锁定为所有行中的所有元素的ASC。同样,rsort()将按DESC顺序对所有列进行排序。这些结果在某些情况下不会满足。我想你可以通过将mod time存储为负整数来破解mod time排序,使其与文件名排序相反。.我离题了。

相关问题