Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > Корректность выражения


Автор: AnemoN 13.12.2012, 01:01
Здравствуйте!

Небольшой вопрос по поводу работы интерпретатора с выражениями следующего вида:

Код

if ( !($var = func($option)) || isset($var['error']) ) {
  // ...
}


Собственно вопрос: гарантировано ли в подвыражении isset($var['error']) переменная $var уже будет содержать возвращенное функцией func значение?

Простой тест:

Код

$foo = -1;

if ( ($foo = 0) || !$foo )
{
  // ...
}


показывает что содержит, но если я кажется когда-то слышал что поведение в таком случае может быть непредсказуемым.
Может кому-то встречался конкретный док, разъясняющий этот момент?

Автор: Arantir 13.12.2012, 01:25
Интерпретатор обрабатывает функции по приоритетам. Там, где приоритет равен - это последовательное выполнение слева направо (в случае логических функций). То есть, в случае ИЛИ: выполнить левую часть, выполнить правую часть, сравнить результаты через ИЛИ.

Интерпретатор не обрабатывает код дальше, если дошел до момента, когда логическое выражение гарантированно примет одно из возможных булевых значений.
То есть, после "false &&" уже нет смысла продолжать. Возможно это просто оптимизация, но благодаря этому весьма распространен и прекрасно существует такой код:
Код
if (isset($var) && $var == "val") { }

И не трудно убедится, что следующий код работать не будет (ошибка "Undefined variable"):
Код
if ($var == "val" && isset($var))

Вот этот код не выдаст ошибки:
Код
if ($some_var = true || $some_other_var == 0) { }
А этот выдаст:
Код

if ($some_var = false || $some_other_var == 0) { }


В вашем случае поведение вполне предсказуемо. Если $var будет равно true, то будет выполнено isset($var['error']), если нет - не будет выполнено. В обеих случаях $var будет присвоено значение до выполнения isset().

Добавлено @ 01:33
Вот док, вполне все разъясняющий:
http://php.net/manual/ru/language.operators.precedence.php

Автор: AnemoN 13.12.2012, 02:22
Спасибо!

Угомонили мою паранойю

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)