PHP игнорирует возвращенную ссылку из функции, которая считается вредной?

У Дерика Ретанса есть старая статья, в которой говорится:

Обратите внимание, что не принимать ссылку от функции, которая возвращает ссылку, вредно. В некоторых случаях PHP будет путаться и вызывать повреждения памяти, которые очень трудно найти и отладить. Также не рекомендуется возвращать статическое значение в качестве ссылки, так как у движка PHP с этим тоже есть проблемы. В PHP 4.3 оба случая могут привести к очень трудно воспроизводимым ошибкам и сбоям PHP и веб-сервера. В PHP 5 все это работает немного лучше. Здесь вы можете ожидать предупреждения, и он будет вести себя «правильно».

Означает ли это, что в PHP 5 нам разрешено игнорировать возвращаемую ссылку из функции?

Под этим я подразумеваю следующее:

function &GetRef(&$array){
    $item =& $array[0];
    return $item;
}

$array = array(0, 1, 2);
$item =& GetRef($array); /* Normal usage of the function using assign by reference
                            also known as "accepting" the reference. */

$item = GetRef($array); /* Notice that here we didn't assign by reference.
                           Are we allowed to ignore the returned reference
                           and simply do normal assignment? */

В Руководстве по PHP говорится:

В отличие от передачи параметров, здесь [возврат по ссылке] вы должны использовать & в обоих местах — чтобы указать, что вы хотите вернуть по ссылке, а не по копии, и чтобы указать, что для $ нужно делать привязку по ссылке, а не обычное присваивание. мое значение.

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

Означает ли это, что мы можем игнорировать возвращаемые ссылки?


person Pacerier    schedule 13.08.2013    source источник
comment
Может быть, вам стоит спросить Дерика Этанса... он единственный, кто точно знает, что он имел в виду под словом "немного лучше".   -  person naththedeveloper    schedule 13.08.2013
comment
@FDL, дело не в этом ... что-то исправлено в PHP 5, и у нас нет сбоев движка, или что-то не полностью исправлено, и нам следует избегать игнорирования возвращаемых ссылок?   -  person Pacerier    schedule 13.08.2013
comment
Учитывая, что PHP 4.3 уже более 10 лет, а движок с тех пор был полностью переписан, я не думаю, что вам должны сниться кошмары по этому поводу.   -  person Mark Baker    schedule 13.08.2013
comment
Я думаю, что если мы говорим о баге, то может быть только два состояния: он исправлен или сохраняется. Немного лучше означает, что ошибка все еще сохраняется - я думаю, других значений быть не может. Поэтому вы должны знать об этом и избегать ситуаций, которые приводят к появлению этой ошибки.   -  person Alma Do    schedule 13.08.2013
comment
@AlmaDoMundo, значит, твое мнение отличается от мнения Марка?   -  person Pacerier    schedule 13.08.2013
comment
Совсем не отличается. Если я не могу быть в чем-то уверен - я обязательно буду избегать ситуаций с чем-то неопределенным. Так что, если нет прямых подтверждений того, что ошибка исправлена, я буду избегать таких случаев. Я согласен с @MarkBaker, что движок можно было бы переписать, но нет гарантии, что ошибка была исправлена.   -  person Alma Do    schedule 13.08.2013
comment
Знаете, есть простой способ получить практический ответ на этот вопрос. Напишите какой-нибудь код, который возвращает ссылку, вызовите его миллиард раз и посмотрите, сколько памяти используется. Если он завершается и не использует более половины ГБ, все в порядке.   -  person cHao    schedule 13.08.2013
comment
@cHao это непросто, и из-за нестабильности этой ошибки есть вероятность, что в вашей конкретной среде и ваших попытках она не появится.   -  person Alma Do    schedule 13.08.2013
comment
Если посмотреть на вопрос по-другому, без какого-либо окончательного подтверждения того, что проблема все еще не существует, почему бы просто не избежать этих ситуаций, если проблема все еще существует.   -  person Anigel    schedule 13.08.2013
comment
Не может быть никаких гарантий, что любая часть программного обеспечения полностью свободна от ошибок: это включает в себя сам PHP. На самом деле, с каждым выпуском есть список изменений, в котором подробно описаны все исправленные ошибки, а также перечислены новые функции.   -  person Mark Baker    schedule 13.08.2013
comment
Однако, если известная ошибка сохраняется в PHP уже более 10 лет и из-за полной перезаписи базового движка, то либо это происходит так редко в реальности, что вам не нужно об этом беспокоиться, либо Ruby/Python Бригада /Java использовала бы его как боеприпас, чтобы доказать, насколько превосходны эти языки, и весь мир узнал бы об этом. Мне? Я буду беспокоиться об этом, если когда-нибудь столкнусь с этим, и я приму свой возврат по эталонным значениям, где это уместно, но в остальном я не собираюсь терять сон из-за этого.   -  person Mark Baker    schedule 13.08.2013
comment
@Anigel: Потому что принимать ссылку, которую вы не собираетесь использовать, бесполезно. Хуже того, это вызывает некоторые магические справочные материалы, которые могут затруднить определение того, где меняются значения ваших переменных.   -  person cHao    schedule 13.08.2013
comment
@MarkBaker, я имею в виду, что дело не в этом. Дело в том, что мы должны принимать возвращенные ссылки или нам разрешено их игнорировать? Я запрашиваю интерфейс.   -  person Pacerier    schedule 13.08.2013
comment
@AlmaDoMundo: Б.С. PHP не просто перебрасывает значения случайным образом и надеется на лучшее. Поведение детерминировано и полностью основано на самом PHP и поведении программы.   -  person cHao    schedule 13.08.2013
comment
In PHP 5, this works all a little bit better. Here you can expect a warning and it will behave “properly”. Хотя язык немного расплывчатый и расплывчатый, это говорит о том, что это не проблема в PHP5. Поскольку PHP является открытым исходным кодом, я мог бы пройти через все это, проверяя для себя, что он действительно исправлен, и что возвращаемые ссылки будут отброшены, если мой код их не принимает; но поскольку Дерик предполагает, что проблема исправлена ​​​​в PHP 5, я склонен верить ему, пока не столкнусь с чем-то, что свидетельствует об обратном.   -  person Mark Baker    schedule 13.08.2013
comment
@cHao, вопрос касается API. Нам разрешено делать что-то подобное? Потому что в противном случае мы не можем гарантировать, что будущая версия будет работать, даже если она работает сейчас....   -  person Pacerier    schedule 13.08.2013
comment
@Pacerier: Вам всегда было разрешено делать что-то подобное. Просто у автора это не очень хорошо получалось до PHP 5. У меня лично никогда не было проблем с этим, и, честно говоря, я все равно нахожу этот абзац бесполезно расплывчатым. Парень показывал диаграммы и объяснял ссылки, как профессионал, а затем придумывал что-то вроде «О, может быть здесь ошибка без дополнительной информации?» Я бы счел весь абзац недействительным, если только он не сможет придумать объяснение.   -  person cHao    schedule 13.08.2013


Ответы (1)


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

В статье говорится о ссылках в контексте PHP 4.3, выпущенного в декабрь 2002 и закрытого в конце 2007 года. Сегодня PHP 4 никогда не следует использовать. Как правило, когда дело доходит до изучения работы с PHP, вы не должны не доверять любой статье, посвященной версиям PHP старше 5.2 (по состоянию на середину 2013 года).

PHP 5.0 включает Zend Engine 2, новую виртуальную машину, на которой работает PHP. Здесь реализованы ссылки. В версии 5.1 представлены некоторые обратно несовместимые изменения в отношении манипулирования возвращаемыми значениями. 5.3 вводит настоящую сборку мусора и устаревает как передача по ссылке во время вызова, так и назначение new по ссылке. Эти важные изменения не рассматриваются в этой доисторической статье.

Означает ли это, что в PHP 5 нам разрешено игнорировать возвращаемую ссылку из функции?

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

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

person Charles    schedule 13.08.2013
comment
Эта статья хороша тем, что в ней все подробно. Жаль, что это для PHP 4. Что касается PHP 5, порекомендуете ли вы какие-либо материалы, в которых подробно рассматриваются ссылки? Материала в руководстве по PHP просто недостаточно. - person Pacerier; 15.08.2013