我正在尝试按日期(最后修改)显示文件数组。
我已经完成了这个购买循环数组并将其排序到另一个数组,但有更简单(更有效)的方法吗?
答案 0 :(得分:90)
为了子孙后代,如果在接受的答案中链接的论坛帖子丢失或不清楚某些人,则需要的相关代码是:
<?php
$myarray = glob("*.*");
usort($myarray, create_function('$a,$b', 'return filemtime($a) - filemtime($b);'));
?>
在我的系统上对此进行了测试并验证了它根据需要按文件mtime排序。我使用类似的方法(用Python编写)来确定我网站上的最新更新文件。
答案 1 :(得分:36)
<?php
$items = glob('*', GLOB_NOSORT);
array_multisort(array_map('filemtime', $items), SORT_NUMERIC, SORT_DESC, $items);
答案 2 :(得分:13)
此解决方案与accepted answer相同,使用匿名函数 1 更新:
$myarray = glob("*.*");
usort( $myarray, function( $a, $b ) { return filemtime($a) - filemtime($b); } );
1 Anonymous functions已于2010年在PHP中引入。原始答案日期为2008年。
答案 3 :(得分:4)
自 PHP 7.4 起,最好的解决方案是使用带有箭头功能的自定义排序:
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)));
答案 4 :(得分:2)
glob()
!如果您要扫描文件夹中的许多文件而没有特殊的通配符,
规则集或任何exec()
,
我建议使用scandir()
或readdir()
。
glob()
慢很多,在Windows上甚至更慢。
引用者: aalfiann
为什么在这个基准测试中,glob似乎变慢了?因为glob会做 如果您这样写
"mydir/*"
,则递归到sub dir。只需确保没有任何子目录即可使glob快速运行。
"mydir/*.jpg"
更快,因为glob不会尝试将文件放入内部 子目录。
基准:
glob()
与scandir()
讨论:
readdir()
与scandir()
readdir vs scandir(堆栈溢出)
readdir()
或scandir()
与这些结合使用,以获得相当整洁的性能。PHP 7.4
usort( $myarray, function( $a, $b ) { return filemtime($a) - filemtime($b); } );
来源: https://stackoverflow.com/a/60476123/3626361
PHP 5.3.0及更高版本
usort($myarray, fn($a, $b) => filemtime($a) - filemtime($b));
如果您想进一步深入兔子洞:
DirectoryIterator
https://www.php.net/manual/en/class.directoryiterator.php
https://www.php.net/manual/en/directoryiterator.construct.php(阅读评论!)
http://paulyg.github.io/blog/2014/06/03/directoryiterator-vs-filesystemiterator.html
<?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']) );
答案 5 :(得分:0)
我知道此线程很旧,但是可以实现更好的性能。接受的答案中的usort()
将多次呼叫filemtime()
。 PHP使用快速排序算法,其平均性能为1.39*n*lg(n)
。该算法每个比较两次调用filemtime()
,因此我们将有28个调用10个目录条目,556个调用100个条目,8340个调用1000个条目,等等。下面的代码对我有用,并且非常有用性能:
exec ( stripos ( PHP_OS, 'WIN' ) === 0 ? 'dir /B /O-D *.*' : 'ls -td1 *.*' , $myarray );