Простой вопрос, простой код. Это работает:
$x = &$_SESSION['foo'];
Это не означает:
$x = (isset($_SESSION['foo']))?&$_SESSION['foo']:false;
Он выдает PHP Parse error: syntax error, unexpected '&'
. Нельзя ли передавать по ссылке при использовании условного оператора, а почему бы и нет? Также случается, если между пробелом есть пробел ?
и &
.
Простой ответ: нет. Вам придется пройти долгий путь с if / else. Это также было бы редким и, возможно, путаным, чтобы иметь ссылку один раз, а значение следующее. Я бы нашел это более интуитивно понятным, но опять же я не знаю вашего кода, конечно:
if(!isset($_SESSION['foo'])) $_SESSION['foo'] = false; $x = &$_SESSION['foo'];
Что касается почему: не знаю, возможно, с этим в этот момент парсер считает что-то копией ценности или созданием ссылки, которая таким образом не может быть определена в точке разбора.
В простом случае это выражение, которое является незаконным;
$c = condition ? &$a : &$b; // Syntax error
может быть написано так:
$c = &${ condition ? 'a' : 'b' };
В вашем конкретном случае, поскольку вы не назначаете по ссылке, если условие является ложным, лучшим вариантом является:
$x = isset($_SESSION['foo']) ? $x = &$_SESSION['foo'] : false;
К сожалению, вы не можете.
$x=false; if (isset($_SESSION['foo'])) $x=&$_SESSION['foo'];
Давай попробуем:
$x =& true?$y:$x;
Ошибка анализа: синтаксическая ошибка, неожиданный «?», Ожидающий T_PAAMAYIM_NEKUDOTAYIM в ...
$x = true?&$y:&$x;
Ошибка анализа: синтаксическая ошибка, неожиданный «&» в ...
Итак, вы видите, он даже не разбирает. Викен, вероятно, прав, почему это запрещено.
Вы можете обойти это с помощью функции:
function &ternaryRef($cond, &$iftrue, &$iffalse=NULL) { if ($cond) return $iftrue; else return $iffalse; } $x = 4; $a = &ternaryRef(true, $x); xdebug_debug_zval('a'); $b = &ternaryRef(false, $x); xdebug_debug_zval('b');
дает:
а:
(refcount = 2, is_ref = 1) , int 4
б:
(refcount = 1, is_ref = 0) , null
Комментарий к этому отчету об ошибке может пролить свет на проблему:
http://bugs.php.net/bug.php?id=53117 .
В сущности, две проблемы с попыткой назначить ссылку из результата тройного оператора:
$x = (expression)
не является ссылочным назначением, даже если (expression)
является ссылкой (это не так, см. пункт 1).