PHP 5.4 Переадресация времени звонка - доступно легкое исправление?

Есть ли способ легко исправить эту проблему или мне действительно нужно переписать весь устаревший код?

PHP Неустранимая ошибка: время прохода по ссылке было удалено в... в строке 30

Это происходит везде, когда переменные передаются в функции как ссылки во всем коде.

Ответ 1

Вы должны указывать вызов по ссылке в определении функции, а не на фактический вызов. Поскольку PHP начал показывать ошибки устаревания в версии 5.3, я бы сказал, что было бы неплохо переписать код.

Из документации:

В вызове функции нет ссылочного знака - только для определения функций. Определений функций достаточно, чтобы правильно передать аргумент по ссылке. Начиная с PHP 5.3.0 вы получите предупреждение о том, что "call-by-pass-by-reference" устарело, когда вы используете & в foo(&$a);.

Например, вместо использования:

// Wrong way!
myFunc(&$arg);               # Deprecated pass-by-reference argument
function myFunc($arg) { }

Использование:

// Right way!
myFunc($var);                # pass-by-value argument
function myFunc(&$arg) { }

Ответ 2

PHP и ссылки несколько неинтуитивны. Если используемые надлежащие ссылки в правильных местах могут обеспечить большие улучшения производительности или избежать очень уродливых обходных решений и необычного кода.

Следующее приведет к ошибке:

 function f(&$v){$v = true;}
 f(&$v);

 function f($v){$v = true;}
 f(&$v);

Ни один из них не должен терпеть неудачу, поскольку они могут следовать приведенным ниже правилам, но, без сомнения, были удалены или отключены, чтобы предотвратить много путаницы.

Если они действительно работали, оба включают избыточное преобразование в ссылку, а второе также включает избыточное преобразование обратно в область ограниченной переменной.

Второй вариант был возможен, позволяя передавать ссылку на код, который не предназначен для работы со ссылками. Это чрезвычайно уродливо для ремонтопригодности.

Это ничего не сделает:

 function f($v){$v = true;}
 $r = &$v;
 f($r);

В частности, он возвращает ссылку обратно в обычную переменную, поскольку вы не запрашивали ссылку.

Это будет работать:

 function f(&$v){$v = true;}
 f($v);

Это означает, что вы передаете ссылку без ссылки, но хотите ссылку, чтобы превратить ее в ссылку.

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

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

 function f(&$v){$v = true;}
 $v = array(false,false,false);
 $r = &$v[1];
 f($r);

Здесь он видит, что вы хотите ссылку и уже имеете ссылку, поэтому оставляете ее в покое. Он также может связывать ссылку, но я сомневаюсь в этом.

Ответ 3

Для тех, кто, как и я, читает это, потому что им нужно обновить гигантский проект наследия до 5.6: поскольку здесь указаны ответы, нет быстрого решения: вам действительно нужно найти каждое возникновение проблемы вручную, и исправить.

Самый удобный способ найти все проблемные строки в проекте (не считая использования полномасштабного статического анализатора кода, который очень точен, но я не знаю никого, который приведет вас к правильной позиции в редакторе сразу же) использовал Visual Studio Code, у которого есть хороший PHP linter встроенный и его функция поиска, которая позволяет искать по Regex. (Конечно, вы можете использовать любой редактор IDE/Code для этого, который выполняет переименование PHP и Regex.)

С помощью этого регулярного выражения:

^(?!.*function).*(\&\$)

можно выполнить поиск по всему проекту для появления &$ только в строках, которые не являются определением функции.

Это все еще вызывает много ложных срабатываний, но облегчает работу.

Браузер результатов поиска VSCode позволяет пройтись и находить оскорбительные строки очень просто: вы просто щелкаете по каждому результату и смотрите на те, которые подчеркивает краска linter. Те, которые вам нужно исправить.