Строгие стандарты: только переменные должны передаваться по ссылке - PullRequest
81 голосов
/ 01 марта 2010
$el = array_shift($instance->find(..))

Приведенный выше код как-то сообщает о строгих стандартах, но это не так:

function get_arr(){
    return array(1,2);
}
$el = array_shift(get_arr());

Так когда же оно сообщит о предупреждении?

Ответы [ 6 ]

93 голосов
/ 01 марта 2010

Рассмотрим следующий код:

error_reporting(E_STRICT);
class test {
    function test_arr(&$a) {
        var_dump($a);   
    }
    function get_arr() {
        return array(1,2);  
    }
}

$t= new test;
$t->test_arr($t->get_arr());

Будет сгенерирован следующий вывод:

Strict Standards: Only variables should be passed by reference in `test.php` on line 14
array(2) {
  [0]=>
  int(1)
  [1]=>
  int(2)
}

причина? Метод test::get_arr() не является переменной и в строгом режиме генерирует предупреждение. Такое поведение крайне неинтуитивно, поскольку метод get_arr() возвращает значение массива.

Чтобы обойти эту ошибку в строгом режиме, либо измените сигнатуру метода, чтобы он не использовал ссылку:

function test_arr($a) {
    var_dump($a);  
}

Поскольку вы не можете изменить подпись array_shift, вы также можете использовать промежуточную переменную:

$inter= get_arr();
$el= array_shift($inter);
8 голосов
/ 01 марта 2010

$instance->find() возвращает ссылку на переменную.

Вы получаете отчет, когда пытаетесь использовать эту ссылку в качестве аргумента функции, не сохраняя ее сначала в переменной.

Это помогает предотвратить утечки памяти и, вероятно, станет ошибкой в ​​следующих версиях PHP.

Ваш второй код выдаст ошибку, если он будет выглядеть так (обратите внимание на сигнатуру функции & in):

function &get_arr(){
    return array(1,2);
}
$el = array_shift(get_arr());

Так что быстрое (и не очень хорошее) исправление будет:

$el = array_shift($tmp = $instance->find(..));

Обычно вы сначала делаете присвоение временной переменной и отправляете переменную в качестве аргумента.

5 голосов
/ 25 ноября 2014

Причиной ошибки является использование внутренней функции Структуры данных программирования PHP, array_shift () [php.net/end].

Функция принимает массив в качестве параметра. Хотя в прототипе array_shift() в «Руководстве» указан амперсанд », в расширенном определении этой функции не содержится предупреждающей документации, а также нет никакого очевидного объяснения того, что параметр фактически передается по ссылке.

Возможно, это / понято /. Однако я не понял, поэтому мне было трудно определить причину ошибки.

Воспроизвести код:

function get_arr()
{
 return array(1,2);
}
$array = get_arr();
$el = array_shift($array);
3 голосов
/ 08 марта 2016

Этот код:

$monthly_index = array_shift(unpack('H*', date('m/Y')));

Необходимо изменить на:

$date_time = date('m/Y');
$unpack = unpack('H*', $date_time);
array_shift($unpack);
3 голосов
/ 01 марта 2010

Второй фрагмент тоже не работает, и вот почему. array_shift - это функция-модификатор, которая изменяет свой аргумент, поэтому ожидает, что ее параметр является ссылкой, и вы не можете ссылаться на то, что не является переменной. См. Объяснения Расмуса здесь: Строгие стандарты: только переменные должны передаваться по ссылке

0 голосов
/ 09 декабря 2016

Что ж, в таких очевидных случаях вы всегда можете сказать PHP подавлять сообщения, используя "@" перед функцией.

$monthly_index = @array_shift(unpack('H*', date('m/Y')));

Возможно, это не лучшая практика программирования для подавления всех ошибок таким образом, но в некоторых случаях (например, в этом) это удобно и приемлемо.

В результате я уверен, что ваш друг SysAdmin будет доволен менее загрязненным «error.log». ;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...