usort(): 数组被用户比较函数修改

47

我有一个网络应用程序,在我们的Linux服务器上运行良好。但是当在Mac OS上使用Zend Community Edition Server,使用PHP 5.3运行时,我们会出现以下错误:

usort():数组被用户比较函数修改

每次页面第一次加载时都会出现这个错误(加载一个页面需要大约2分钟时间,在Linux服务器上,该页面可以在1秒钟内加载完成)。

是否有其他人遇到过此问题或者有任何想法如何解决该问题?我尝试过调整PHP和Apache内存设置,但没有成功。

4个回答

89

即使您不更改数组,也有一个 PHP 错误可能会导致此警告。

简而言之,如果任何 PHP 调试函数检查排序数组,它们将更改引用计数并欺骗 usort() 让它认为您已经更改了数据。

因此,在您的排序函数中(或从中调用的任何代码中)执行以下任何操作都会导致警告:

  • 调用任何排序数据的 var_dumpprint_r
  • 调用 debug_backtrace()
  • 抛出任何异常-任何异常-甚至只是创建一个异常

该错误影响所有 PHP 5 版本 >= 5.2.11,但不影响 PHP >= 7。有关详细信息,请参见错误报告

据我所见,唯一的解决方法要么是“不要这样做”(这对于异常来说有点困难),要么使用错误抑制运算符 @usort() 忽略所有错误。


12
让我们投票支持修复这个bug。 https://bugs.php.net/bug.php?id=50688 - Felipe
2
我想补充一点,你不必 throw 一个异常。只需使用 new 创建它,也会触发警告。 - qbolec
sprintf 也会触发这个错误吗?这个错误出现在 Wordpress 4.0 管理面板上... 引用的文件是 wp-includes\class-wp-theme.php 的第 1208 行,使用 uasort 的函数被 wp-admin\includes\theme.php 和其他两个文件各调用一次... 它们都有 sprintf,但没有 print_r/var_dump/debug 之类的东西或者抛出异常。目前我按照你的建议使用了 @uasort 来忽略它,这样就不会再搞乱仪表盘了。 - Armfoot
3
显然,这个问题在“PHP 7”中已经得到了修复。 - Donal Fellows

8
为了解决这个问题,我们可以按照以下步骤处理:
1)使用error_reporting
$a = array('id' => 2,'val' => 3, 'ind' => 3);
$errorReporting = error_reporting(0);
usort($a);
error_reporting($errorReporting);

2) 使用 @usort($a);

$a = array('id' => 2,'val' => 3, 'ind' => 3);
@usort($a);

1
我发现在使用PHP5.4时,使用error_log($message, $message_type, $destination, $extra_headers)记录日志会导致这个错误,当我清除日志条目后问题得到解决。可以通过禁用和恢复排序函数后暂时停止记录日志。

1

Linux系统上的PHP版本是多少?

两个系统的error_reporting级别是否相同?尝试将它们都设置为E_ALL。

警告几乎肯定不是在撒谎。它说你传递给usort()的比较函数正在更改你试图对其进行排序的数组 - 这肯定会使usort花费很长时间,可能是永远!

我的第一步将是研究比较函数,并弄清楚为什么会发生这种情况。如果linux系统使用的是5.3版本之前的预先版本,则有可能某些比较函数中使用的语言函数的行为存在差异。


两台服务器上都是相同版本的PHP,即PHP 5.3.2。我将检查比较函数。 - Michael
如果版本相同,我非常希望确保代码实际上是相同的并且输入也是相同的。但是查看警告指向的任何行通常是一个好的开始。如果您找不到问题,您可能想要将比较函数和一些示例数据粘贴到您的问题中。 - timdev

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