usort(): массив был изменен пользовательской функцией сравнения

У меня есть веб-приложение, которое отлично работает на наших серверах Linux, но при работе в Mac OS с сервером Zend Community Edition с использованием PHP 5.3 мы получаем ошибку:

usort(): массив был изменен пользовательской функцией сравнения

каждый раз, когда страница загружается в первый раз (для загрузки страницы требуется около 2 минут, на серверах Linux страница загружается за 1 секунду).

Кто-нибудь еще сталкивался с этим или знает, как я могу решить эту проблему, я безуспешно пытался поиграть с настройками памяти PHP и Apache.


person Michael    schedule 13.07.2010    source источник


Ответы (4)


Существует ошибка PHP, которая может вызвать это предупреждение, даже если вы не изменяете массив.

В краткой версии, если какие-либо функции отладки PHP исследуют массив сортировки, они изменят счетчик ссылок и обманут usort(), заставив его думать, что вы изменили данные.

Таким образом, вы получите это предупреждение, выполнив любое из следующих действий в своей функции сортировки (или любом коде, вызываемом из нее):

  • вызов var_dump или print_r для любых данных сортировки
  • звоню debug_backtrace()
  • создание исключения - любого исключения - или даже просто создание исключения

Ошибка затрагивает все версии PHP 5 >= 5.2.11, но не влияет на PHP >= 7. См. отчет об ошибке для получения дополнительной информации.

Насколько я вижу, единственным обходным решением является либо «не делать этого» (что довольно сложно для исключений), либо использовать оператор подавления ошибок @usort() для игнорирования всех ошибок.

person Achronos    schedule 11.06.2012
comment
Давайте проголосуем за то, чтобы эта ошибка была исправлена, люди. bugs.php.net/bug.php?id=50688 - person Felipe; 16.08.2012
comment
Я бы просто добавил к этому, что вам не нужно генерировать исключение. Простое создание с использованием new также вызовет предупреждение. - person qbolec; 09.07.2013
comment
sprintf также запускает это? Эта ошибка появляется на панели администратора Wordpress 4.0... Ссылочный файл - wp-includes\class-wp-theme.php в строке 1208, а функция, использующая uasort, вызывается wp-admin\includes\theme.php и двумя другими файлами по одному разу... Все они имеют sprintfs, но нет ни print_r/var_dump/debug, ни бросков. На данный момент я использовал @uasort для игнорирования, как вы предложили, и это больше не портит панель инструментов. - person Armfoot; 10.09.2014
comment
Судя по всему, это «исправлено в PHP 7». - person Donal Fellows; 22.03.2016

Чтобы решить эту проблему, мы можем справиться, как показано ниже.

1) используйте отчет об ошибках

$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);
person panditharshad    schedule 06.03.2014

Какая версия PHP установлена ​​на Linux?

Одинаковы ли уровни error_reporting на обоих устройствах? Попробуйте установить их обоих на E_ALL.

Предупреждение почти наверняка не лжет. Это говорит о том, что функция сравнения, которую вы передаете в usort(), меняет массив, который вы пытаетесь отсортировать — это определенно может заставить usort занять много времени, возможно, навсегда!

Моим первым шагом было бы изучить функцию сравнения и выяснить, почему это происходит. Вполне возможно, что если в Linux-боксах используется версия до 5.3, есть некоторая разница в поведении некоторых языковых функций, используемых в функции сравнения.

person timdev    schedule 13.07.2010
comment
Это одна и та же версия PHP на обоих серверах, PHP 5.3.2. Я проверю функции сравнения. - person Michael; 13.07.2010
comment
Если версии одинаковы, я бы очень хотел убедиться, что код действительно одинаков, и все входные данные одинаковы. Но для начала неплохо посмотреть на любую строку, на которую указывает предупреждение. Возможно, вы захотите вставить свою функцию сравнения и некоторые примеры данных в свой вопрос, если вы не обнаружите проблему самостоятельно. - person timdev; 13.07.2010

Я обнаружил, что при использовании PHP5.4 ведение журнала с error_log($message, $message_type, $destination, $extra_headers) вызывает эту ошибку, когда я очищаю записи журнала, моя проблема решена. Ведение журнала может быть временно приостановлено путем отключения и восстановления функции ведения журнала после сортировки.

person user3740692    schedule 14.06.2014