Php glob()-按上次修改的日期时间戳对文件数组排序

Php glob()-按上次修改的日期时间戳对文件数组排序,php,arrays,sorting,filemtime,Php,Arrays,Sorting,Filemtime,我试图按日期(上次修改)的顺序显示文件数组 我已经在数组中循环并将其排序到另一个数组中,但是有更简单(更有效)的方法吗 警告create_function()自PHP 7.2.0起已被弃用。非常不鼓励依赖此功能 为子孙后代着想,如果接受答案中链接的论坛帖子丢失或对某些人来说不清楚,则需要相关代码: <?php $myarray = glob("*.*"); usort($myarray, create_function('$a,$b', 'return filemtime($a) - f

我试图按日期(上次修改)的顺序显示文件数组

我已经在数组中循环并将其排序到另一个数组中,但是有更简单(更有效)的方法吗

警告
create_function()
自PHP 7.2.0起已被弃用。非常不鼓励依赖此功能

为子孙后代着想,如果接受答案中链接的论坛帖子丢失或对某些人来说不清楚,则需要相关代码:

<?php

$myarray = glob("*.*");
usort($myarray, create_function('$a,$b', 'return filemtime($a) - filemtime($b);'));

?>

在我的系统上对此进行了测试,并验证了它是否按文件mtime进行了所需排序。我也使用了类似的方法(用Python编写)来确定网站上最后更新的文件。

此解决方案与使用匿名函数1更新的解决方案相同:

<?php
$items = glob('*', GLOB_NOSORT);
array_multisort(array_map('filemtime', $items), SORT_NUMERIC, SORT_DESC, $items);


2010年PHP中引入了1。原始答案是2008年的。

我知道这个线程很旧,但这可以用更好的性能来完成。接受答案中的
usort()
会多次调用
filemtime()
。PHP使用的快速排序算法的平均性能为
1.39*n*lg(n)
。该算法每次比较调用两次
filemtime()
,因此我们将对10个目录条目进行28次调用,对100个条目进行556次调用,对1000个条目进行8340次调用,等等。下面的代码对我来说效果很好,性能也很好:

exec ( stripos ( PHP_OS, 'WIN' ) === 0 ? 'dir /B /O-D *.*' : 'ls -td1 *.*' , $myarray );

由于PHP 7.4最好的解决方案是使用带有箭头功能的自定义排序:

usort($myarray, fn($a, $b) => filemtime($a) - filemtime($b));
您还可以使用spaceship操作符,它适用于所有类型的比较,而不仅仅是整数比较。在这种情况下,它不会有任何区别,但在所有排序操作中使用它是一种很好的做法

usort($myarray, fn($a, $b) => filemtime($a) <=> filemtime($b));
usort($myarray,fn($a,$b)=>filemtime($a)filemtime($b));
如果要按相反顺序排序,可以取消条件:

usort($myarray, fn($a, $b) => -(filemtime($a) - filemtime($b)));
// or 
usort($myarray, fn($a, $b) => -(filemtime($a) <=> filemtime($b)));
usort($myarray,fn($a,$b)=>-(filemtime($a)-filemtime($b));
//或
usort($myarray,fn($a,$b)=>-(filemtime($a)filemtime($b));
<代码> 2020年年-如果你关心性能,考虑不要使用<代码> GULL()/<代码>!
如果要在不使用特殊通配符的情况下扫描文件夹中的大量文件,
规则集,或任何
exec()

我建议
scandir()
,或者
readdir()

glob()


报价人:

为什么glob在这个基准测试中显得较慢?因为glob就行了 如果您这样编写,则递归到sub dir
“mydir/*”

只要确保没有任何子目录使glob快速

“mydir/*.jpg”
速度更快,因为glob不会尝试将文件放入其中 副署长


基准测试:
glob()
vs
scandir()

(外部)


讨论:
readdir()
vs
scandir()

(堆栈溢出)


readdir()
scandir()
与这些结合使用,可获得相当出色的性能

PHP7.4

usort($myarray,function($a,$b){returnfilemtime($a)-filemtime($b);})

来源:

PHP 5.3.0及更新版本

usort($myarray,fn($a,$b)=>filemtime($a)-filemtime($b))

来源:


如果你想深入兔子洞:

目录迭代器


(阅读评论!)


最后但并非最不重要的是,我的演示!
你找到这个了吗?(刚刚在谷歌上搜索了你的问题标题):效果很好。我想要相反的顺序,所以我在函数定义字段中将$a与$b交换。谢谢你,杰!每次进行比较时(每个文件多次),这段代码都会访问文件系统。根据文件系统的位置,这可能会非常慢。此外,如果在排序过程中写入了任何文件,那么更改文件时间可能会导致奇怪的排序结果,这取决于usort使用的算法。我建议使用,这样可以避免所有这些问题。如果您使用的是PHP5.3.0或更新版本,则应该使用本机匿名函数。将
array\u map
的结果作为要通过引用传递的参数传递是没有意义的。你会把它分类,但那又怎么样?您不再拥有它。
array\u map
的结果用于对
$items
数组进行排序,该数组也通过引用传递。我明白了。我想这是可行的,类似的方法甚至在php.net的
array\u multisort
页面上有记录。我认为这项任务有更合适的功能,但我会收回我的反对票。或者如果我能。。。抱歉。在现实生活中,尽管它看起来像一个性感的单行本,但经过测试并没有正确排序。@ViktorJoras您可以发布一个指向您的测试代码的链接吗?现在是2019年,这应该是可以接受的答案。PHP7不再允许“创建函数”。。因此,最好的解决方案是使用匿名函数(或引用)
usort($myarray, fn($a, $b) => -(filemtime($a) - filemtime($b)));
// or 
usort($myarray, fn($a, $b) => -(filemtime($a) <=> filemtime($b)));
<?php
function files_attachment_list($id, $sort_by_date = false, $allowed_extensions = ['png', 'jpg', 'jpeg', 'gif', 'doc', 'docx', 'pdf', 'zip', 'rar', '7z'])
{
    if (empty($id) or !is_dir(sprintf('files/%s/', $id))) {
        return false;
    }
    $out = [];
    foreach (new DirectoryIterator(sprintf('files/%s/', $id)) as $file) {
        if ($file->isFile() == false || !in_array($file->getExtension(), $allowed_extensions)) {
            continue;
        }

        $datetime = new DateTime();
        $datetime->setTimestamp($file->getMTime());
        $out[] = [
            'title' => $file->getFilename(),
            'size' => human_filesize($file->getSize()),
            'modified' => $datetime->format('Y-m-d H:i:s'),
            'extension' => $file->getExtension(),
            'url' => $file->getPathname()
        ];
    }

    $sort_by_date && usort($out, function ($a, $b) {
        return $a['modified'] > $b['modified'];
    });

    return $out;
}

function human_filesize($bytes, $decimals = 2)
{
    $sz = 'BKMGTP';
    $factor = floor((strlen($bytes) - 1) / 3);
    return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$sz[$factor];
}

// returns a file info array from path like '/files/123/*.extensions'
// extensions = 'png', 'jpg', 'jpeg', 'gif', 'doc', 'docx', 'pdf', 'zip', 'rar', '7z'
// OS specific sorting
print_r( files_attachment_list(123) );

// returns a file info array from the folder '/files/456/*.extensions'
// extensions = 'txt', 'zip'
// sorting by modified date (newest first)
print_r( files_attachment_list(456, true, ['txt','zip']) );