PHP 5.3 и присвоение возвращаемого значения new по ссылке
Назначение возвращаемого значения new по ссылке было deprecated в PHP 5.3. Таким образом,
$obj =& new Foo();
теперь выдает ошибку E_DEPRECATED
.
При обновлении большого приложения с большим количеством устаревшего кода до 5.3 это приводит к множеству нежелательных уведомлений.
Как потенциальное решение этой проблемы, я рассматриваю использование регулярного выражения для поиска и замены всех экземпляров =& new
на = new
. Например, следующее найдет все файлы PHP и уничтожит все экземпляры =& new
:
find ./ -name '*.php' | xargs perl -p -i -e 's/=(\s*)&(\s*)?new\b/= new/g'
Ищете ответы на следующие вопросы:
- Будет ли это работать отлично? С какими потенциальными проблемами я могу столкнуться?
- Если нет, примеры кода, в которых замена
=& new
на = new
изменит поведение в PHP 5.3.
- Любые примеры популярных библиотек с этим, как известно, вызовут проблему.
- Какие еще идеи вы рекомендуете решать с фиксацией огромных количеств
=& new
?
Я подозреваю, что это будет работать очень хорошо, но ищет краевые случаи, где я могу столкнуться с проблемами. Да, я знаю, что могу просто изменить настройки отчетов об ошибках. Но я не хочу скрывать уведомления, я хочу их исправить.
Ответы
Ответ 1
Ваше чувство правильно. Это будет нормально работать, но есть случаи, когда это не так.
Использование =&
имеет эти различия с =
:
-
=&
попытается сделать правильную сторону ссылкой; =
не будет - даже если правая сторона может дать ссылку, как функция, которая возвращается по ссылке.
-
=&
сломает старый набор ссылок и поместит левую и правую стороны как в новую, а =
изменит значение всех элементов в том же наборе ссылок, что и левая сторона, на значение с правой стороны.
Первое различие и половина второго в этом случае не имеют значения. После назначения будет только одна переменная со значением нового объекта *, а одноэлементные наборы ссылок не имеют смысла. Однако факт, что =&
нарушает предыдущий набор ссылок, является значительным:
<?php
$g = 4;
$v =& $g;
$v = new stdclass();
var_dump($g); // object(stdClass)#1 (0) { }
$g = 4;
$v =& $g;
$v =& new stdclass();
var_dump($g); // int(4)
* Если, возможно, конструктор не протекает ссылка, но даже если он протекает, $this
внутри конструктора может быть другой переменной, даже если он указывает на тот же объект. Поэтому я сомневаюсь, что из-за этого можно наблюдать разницу в поведении.
Ответ 2
Да, вы должны просто заменить =& new
на = new
. Объекты передаются по ссылке по умолчанию в PHP 5.3, поэтому никакое поведение не изменится.
+1 для фиксации уведомлений вместо их скрытия.
Ответ 3
Не должно быть никаких проблем. В худшем случае это немного замедлит ваше приложение на PHP 4, но оно определенно не изменит функциональность.
Единственная проблема, с которой вы могли теоретически столкнуться, заключается в том, что кто-то написал строку =& new
в строке. Я знаю, это очень маловероятно, но если вы хотите заменить действительно только все вхождения '=' T_WHITESPACE? '&' T_WHITESPACE? T_NEW
, вы должны сделать это, используя Tokenizer.