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()
vsscandir()
(外部)
讨论:readdir()
vsscandir()
(堆栈溢出)
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']) );