使用filemtime()和usort()对文件进行排序会得到随机的结果。

4

我正在使用 usort()filemtime() 通过修改日期对文件进行排序,但它随机返回错误的顺序。我猜我漏掉了一些非常简单的东西,但我无法弄清楚是什么。

usort($user_files, function($a, $b) {
    return filemtime($a) > filemtime($b);
});
foreach ($user_files as $f) {
    echo $f . "<br />";
}

接下来我上传了文件。完整代码

上传文件1.txt...10.txt以测试结果,结果显示如下:

6.txt
5.txt
4.txt
3.txt
2.txt
1.txt
7.txt Uploaded!

如预期所料。当我到达8.txt时:

6.txt
7.txt
5.txt
4.txt
2.txt
3.txt
1.txt
8.txt Uploaded!

另一次,一切都很好,直到我到达10.txt

7.txt
8.txt
9.txt
6.txt
5.txt
2.txt
3.txt
4.txt
1.txt
10.txt Uploaded!

当使用ls -t时,返回:

10.txt  9.txt  8.txt  7.txt  6.txt  5.txt  4.txt  3.txt  2.txt  1.txt

所以...在那里发生了什么?
Debian Wheezy 7.4, up-to-date.
PHP Version 5.4.4-14+deb7u8
Linux pc 3.2.0-4-amd64 #1 SMP Debian 3.2.54-2 x86_64
FPM/FastCGI
nginx/1.2.1

1
你的代码从pastebin上消失了。 - Craig Trader
2个回答

4

人们使用 usort 来进行排序,参考文献:http://www.php.net/manual/en/function.usort.php

value_compare_func

比较函数必须返回整数,如果第一个参数被认为小于、等于或大于第二个参数,则分别返回小于零、等于零或大于零。

但是所提供的回调只有 ">" 运算符:

{
    return filemtime($a) > filemtime($b);
}

这位先生 (http://www.php.net/manual/en/language.operators.comparison.php) 表示,“Greater than” 即 > 运算符仅返回 true 或 false,而不是所需的负数、零或正数。

$a > $b Greater than 如果 $a 严格大于 $b,则为 TRUE。

你认为在两个 filemtime 之间使用“减法” "-" 运算符如何?因为该先生再次表示,filemtime 是整数(http://www.php.net/manual/en/function.filemtime.php)。

此站点上有重复答案 (使用 filemtime usort 进行谷歌搜索,并选择第一项结果): Order this array by date modified?,答案出自 Michael Berkowski,他表示:

  if (filemtime($a) === filemtime($b)) return 0;
  return filemtime($a) < filemtime($b) ? -1 : 1; 

谢谢!但是那个方法并没有起作用。奇怪的是,现在似乎每上传第六个文件时顺序都会被打乱。我猜测问题与 usort() 无关,但我无法找出原因。我已经编辑了问题并附上了完整的代码。 - Alex
1
即使这不是正确答案,这也是一个好的猜测,因为某些处理可能比1秒钟更短的时间来处理多个文件。 - Alain Tiemblo

0

我找到了问题所在,如预期的一样,它与usort无关。用来获取文件的函数只获得文件名,而非它们的绝对路径。因此,filemtime被调用时传入的是一个无意义的字符串。我不知道为什么PHP没有对此发出任何警告。


300元赏金求解决一个简单的用户错误 :) 但是没有警告,因为“2.txt”是有效的路径。它只是找不到文件,因此返回FALSE作为失败。而且很明显你只得到了文件名。因为你的测试foreach与usort函数使用了相同的数据。 - Hugo Delsing

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接