отсутствие Notice при использовании reference

tony2001

TeaM PHPClub
отсутствие Notice при использовании reference

Объясните, пожалуйста, кто-нибудь почему данный код ведет себя таким образом:

PHP:
//переменная $undefined не определена, но нотайса НЕТ
error_reporting(E_ALL);
$test = &$undefined;
причем, var_dump($undefined); после этого честно говорит "NULL", т.е. isset($undefined) === false.

с другой стороны:
PHP:
//переменная $undefined не определена и нотайс ЕСТЬ
error_reporting(E_ALL);
$test = $undefined;
мне непонятна логика поведения РНР в данном случае.
у кого-нибудь есть варианты объяснения?

для тех, кто скажет, что это "указатель как в Си" и указывает он на случайную область памяти:
"They are not like C pointers, they are symbol table aliases." (с) http://www.php.net/manual/en/language.references.php
 

tony2001

TeaM PHPClub
более интересный вариант (собственно, на нем и было найдено):
PHP:
error_reporting(E_ALL);

function test(&$var) {
 echo $var;
}

test($no_such_var); //переменной такой нет. но и нотайса тоже.
 

Profic

just Profic (PHP5 BetaTeam)
Про последний пример: PHP "создает" переменую, если ее не существовало при передаче по ссылке в функцию, видимо для того, чтобы облегчить жизнь начинающим программерам.

Причем заметь, что такой синтаксис (без начального определения переменной) используется в куче примеров мануала, где используются ссылки. Не думаю, что разработчики писали бы в примеры неверный код :)
 

tony2001

TeaM PHPClub
>PHP "создает" переменую, если ее не существовало при
>передаче по ссылке в функцию, видимо для того, чтобы
>облегчить жизнь начинающим программерам.
он создает ее и при просто присвоении.
только при этом он "говорит" об этом нотайсом.
мне интересно почему здесь нотайса нет.
 

KR

alive in new life
Похоже Profic прав.

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

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

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

Tronyх

Новичок
При в случае построчной предкомпилляции ПХП может предполагать что переменная, на которую ссылаются может быть определена позже и вполне логично не выдает нотайса.
Этот код как раз это и подтверждает:
<?
$test1=&$test2;
echo $test1; // пусто

$test2=123;
echo $test1; // 123
?>
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
Есть подозрение, что так сделано для того, чтобы код наподобие
PHP:
preg_match('/preg/', 'string', $matches);
не вываливал notice, если $matches неопределена до вызова функции (а с какой радости её определять?). а отсутствие notice в случае
PHP:
$test = &$undefined;
побочное явление.
 

Profic

just Profic (PHP5 BetaTeam)
2Тони:
Ответ на твой перваначальный вопрос: потому что PHP так написан :)
После беглого просмотра исходников PHP (версия 4.2.1, новее под рукой нет), вот что там обнаружил (в меру моих знаний C):

1) при компиляции идет проверка наличия переменной (на которую ссылаются) и если она не определена, то ссылка устанавливается в NULL, но при этом запоминается название переменной.

2) при выполнении проверяется, не объявлена ли переменная с именем, запомненным во время компиляции, если да, то она связывается, если нет, то так и остается NULL.
В общем они не зря пишут, что "They are not like C pointers, they are symbol table aliases." Это именно алиасы по именам переменных, не более. Но все-таки их можно "обявить" ($test2 =& $test2), а только потом "проинициализировать" ($test2 = '123'), как в С.

ЗЫ. Под "именем переменной" в данном случая я понимаю всё, что может быть представлено как ссылка (переменные, индексы массивов, свойства объектов и т.д., но не индексы строк и т.д.).
 

Screjet

Новичок
Своеобразное поведение ПХП, по моему вполне логичное..
Передача по ссылке в функции, по моему, ориентирована на получение определенного значения, а не передачу его:
PHP:
function myFunc( &$myLink ){
   $myLink = "abc";
}
Потому, видать, вполне умесно ее создание.
 

tony2001

TeaM PHPClub
Sad Spirit:
ага, вот это уже похоже на правду, хотя можно было бы сделать в данном случае не передачу переменной по ссылке, а передачу имени переменной.

2 олл:
господа, то что, "создание уместно" и что "РНР так сделан" я _прекрасно_ понимаю.
нотайс хочу!
пускай хоть 38 раз создает, но нотайс хочется при этом.

хотя, объяснение Сэд Спирита очень похоже на правду.
 

rihad

Guest
//переменная $undefined не определена, но нотайса НЕТ
error_reporting(E_ALL);
$test = &$undefined;
После этого isset($test) тоже вернет false, так что по сути это no-op, т.е. ты ничего не сделал. И нотиса нет, логично. А вызов функции - это просто частный случай присваивания lv = rv.

P.S.: не стоит принимать ПХП близко к сердцу, он не был создан для того, чтобы быть элегантным или последовательным. Здесь нет четких правил Java или свободы действий C++. Понятие того, что есть "последовательно" эволюционирует у авторов по мере репорта багов.
 

Varg

Guest
Странные вы.

По крайней мере в варианте func(&$var) {} нотайса быть не должно точно. Это было бы нелогично. И данная конструкция вполне может _создавать_ переменную или объект исходя из внешних(иных) переменных. Не вижу ничего багового здесь.
 
Сверху