Функция array_shift()
принимает один параметр по ссылке. Передача литерала массива приводит к фатальной ошибке:
$ php -r ‘var_export (array_shift (array («Test # 0»));’; echo
Неустранимая ошибка: только переменные могут быть переданы по ссылке в коде командной строки в строке 1
Это не так, как ожидалось. Тем не менее, PHP ведет себя странно, когда функция вызывается с call_user_func_array:
<?php
var_export(call_user_func_array("array_shift", array(array("Test #1"))));
echo "\n";
$arg1 = array("Test #2");
var_export(call_user_func_array("array_shift", array($arg1)));
echo "\n";
$args = array(array("Test #3"));
var_export(call_user_func_array("array_shift", $args));
echo "\n";
Когда выполнено:
$ php test.php
«Тест № 1»
Предупреждение: параметр от 1 до array_shift () должен быть ссылкой, значение указано в /Users/kcc/test.php в строке 6
НОЛЬПредупреждение: параметр от 1 до array_shift () должен быть ссылкой, значение указано в /Users/kcc/test.php в строке 10
НОЛЬ
Понятно что call_user_func_array()
не вызовет фатальную ошибку, но почему первая форма работает нормально?
От call_user_func_array () документация:
До PHP 5.4 ссылочные переменные в
param_arr
передаются в функцию по ссылке, независимо от того, ожидает ли функция передачи соответствующего параметра по ссылке. Эта форма передачи времени вызова по ссылке не создает уведомления об устаревании, но, тем не менее, она устарела и была удалена в PHP 5.4. Кроме того, это не относится к внутренним функциям, для которых признается подпись функции. Передача по значению, когда функция ожидает параметр по ссылке, приводит к предупреждению иcall_user_func()
вернутьFALSE
(есть, однако, исключение для переданных значений с числом ссылок = 1, например в литералах, поскольку они могут быть превращены в ссылки без вредных последствий — но также без записи в это значение, имеющее какой-либо эффект -; однако не полагайтесь на это поведение, так как счетчик ссылок является деталью реализации, а обоснованность такого поведения сомнительна).
(акцент мой)
Начиная с PHP 5.4, call_user_func_array()
передает все свои аргументы по значению указанному $callback
, за исключением случая, выделенного жирным шрифтом в приведенной выше ручной цитате.
В Test #1
у вас есть чистый литерал, поэтому вы столкнулись со специальным исключением, описанным в документации: литерал можно превратить в ссылку без нежелательных побочных эффектов (потому что он будет просто отброшен, когда call_user_func_array()
готово).
В Test #2
а также Test #3
у вас нет чистого литерала, и потому что внутренне, array_shift
определяется как получение его параметра по ссылке, call_user_func_array()
поднимает предупреждение, описанное выше.
В PHP 7 Test #1
«исправлено» и теперь корректно выдает предупреждение.
Других решений пока нет …