О логическом операторе

#php

#php

Вопрос:

вот код

 $a = 2;
$a amp;amp; $a = 1;

var_dump( $a ); // result 1
  

Почему $a равно 1?

Согласно документу, логический оператор ‘amp;amp;’ имеет больший приоритет, чем оператор assign, его следует интерпретировать как ($a amp;amp; $ a) = 1, тогда должна быть синтаксическая ошибка.

Комментарии:

1. Ну, что вы ожидаете , что произойдет?

2. @NiettheDarkAbsol: Я бы надеялся, что это выдаст какую-то ошибку!

3. @NiettheDarkAbsol Как документ, он должен интерпретироваться как ($ a amp;amp; $ a) = 1, тогда должна быть синтаксическая ошибка

Ответ №1:

Из документации

Примечание:
Хотя = он имеет более низкий приоритет, чем большинство других операторов, PHP все равно допускает выражения, подобные следующему: if (!$a = foo()) , и в этом случае возвращаемое значение foo() помещается в $a .

В документации не указано, какие правила соблюдаются на этом этапе, но мы можем сделать вывод, что ваш код эквивалентен этому:

 $a amp;amp; ($a = 1)
  

Поскольку amp;amp; он «ленив» в том смысле, что он не будет утруждать себя оценкой дальнейших аргументов, если найдет тот, который является ложным, это означает, что $a он будет установлен только 1 в том случае, если он ранее содержал истинное значение (в вашем случае, 2 является истинным). Если бы вы установили $a = 0 , то он остался бы 0 .

Комментарии:

1. Я не думаю, что цитата «также» имеет здесь какое-либо отношение; порядок оценки и приоритет, как правило, не связаны между собой. темы.

2. @OliCharlesworth Я думаю, это помогает подчеркнуть, что порядок вычисления не всегда может быть точным, но я могу неправильно его интерпретировать.

3. Приоритет — это то, как создается AST . Эта 2-я цитата относится к таким вещам, как a() b() ; не определено, вычисляется ли a or b (т. Е. Вызывается) первым.

4. @OliCharlesworth А, понятно. Это имеет смысл.

5. Я согласен с @OliCharlesworth по поводу цитаты, но ключ находится внутри "otherwise you would have an invalid left-hand-side for your assignment" . Это основная причина, почему все так, как есть: оно не может быть оценено в другом порядке.

Ответ №2:

То, как это написано, вы говорите то же самое, что и это

 $a = 2;
if($a) $a = 1;
  

Поскольку 2 это что-то, оно завершается успешно и изменяется $a на 1.

Итак, почему он это делает? У вас есть утверждение, что $a = 2 ; Здесь нет порядка операций, поэтому PHP обрабатывает его. Порядок операций вступает в силу со вторым оператором. Помните, $a что это ЧТО-ТО (т.Е. Правдивое). Давайте немного изменим ваш код

 $a = 0;
$a amp;amp; $a = 1;
echo $a;
  

Как вы можете видеть, $a теперь является ложным. Таким образом, порядок не позволяет скрипту изменять значение, и вывод скрипта 0

Комментарии:

1.Но, как говорится в OP, amp;amp; предполагается, что он имеет более высокий приоритет, чем присваивание. Таким образом, код OP должен быть эквивалентен ($a amp;amp; $a) = 1; .

2. @OliCharlesworth Имеет ли какое-либо значение, что это недопустимый код? Для меня это не имеет смысла.

3. @WesleyMurch: Возможно. Таковы ли правила для операторов PHP «Следуйте таблице приоритетов, если это не приведет к чему-то бессмысленному, и в этом случае попробуйте … что-нибудь еще»?

Ответ №3:

 $a amp;amp; $a = 1;
  

является выражением логического типа. Поскольку $a это верно, вычисление выражения продолжается до второй части, которая является присваиванием. Как побочный эффект присваивания, $a теперь выполняется 1 .

Если $a бы в начале было 0, в конце оно осталось бы 0, поскольку вычисление выражения было бы прекращено сразу после проверки первого условия.

Комментарии:

1. Привязка вложенных выражений к операторам, по определению, связана с приоритетом.

2. Верно, что «ничего общего с» преувеличивает. Но тот факт, что выражение вычисляется как $a amp;amp; ($ a = 1), а не интерпретирует $ a amp;amp; $ a как значение lvalue, не из-за приоритета оператора, а выглядит гораздо более похожим на «запасной вариант» на случай, если значение lvalue недопустимо.