Синтаксический сюрприз PHP с условным оператором?: И ИЛИ

Сегодня мне открыли рот следующее:

$asdf = ((1 OR true) ? "asdf" : "fdsa");
var_dump($asdf); // print "asdf"

$asdf = (1 OR true) ? "asdf" : "fdsa";
var_dump($asdf); // print "asdf"

$asdf = (1 OR true ? "asdf" : "fdsa");
var_dump($asdf); // print true

$asdf = 1 OR true ? "asdf" : "fdsa";
var_dump($asdf); // print 1

Хорошо, последнее меня не сильно удивляет, а третье? Кто-нибудь может объяснить?


person Stefano    schedule 14.08.2015    source источник


Ответы (3)


Все дело в приоритете операторов и их ассоциативности

http://php.net/manual/en/language.operators.precedence.php

or имеет более низкий приоритет, чем =, поэтому он будет выполнен первым

so $asdf = 1 OR true ? "asdf" : "fdsa";

будет что-то вроде

($asdf = 1) or true ? :"asdf" : "fdsa" поэтому он напечатает 1.

$a or $b проверьте, истинно ли $ a или $ b, если $ a истинно, тогда оно возвращается и даже не проверяет $ b

В третьем случае

$asdf = (1 OR true ? "asdf" : "fdsa");

() имеет более высокий приоритет, чем =, поэтому он будет выполнен перед назначением.

Чтобы доказать это

измените OR на ||, имеющий более высокий приоритет, чем =

$asdf = 1 || true ? "asdf" : "fdsa";

var_dump($asdf); // print asdf
person Robert    schedule 14.08.2015
comment
Но как, черт возьми, (1 OR true ? "asdf" : "fdsa") оценивается как true, а не "asdf"? - person Bergi; 14.08.2015
comment
потому что (1 OR asdf) верно: P - person Robert; 14.08.2015
comment
Ах, он преобразует результат в логическое значение. PHP, а не что-то еще. - person Bergi; 14.08.2015
comment
Да, это логичное выражение. - person Robert; 14.08.2015
comment
Хороший ответ, но разве вы не предполагаете, что читатель знает, что ? имеет более высокий приоритет, чем OR? Похоже, вы пропустили ту часть объяснения, где $asdf = (1 OR true ? "asdf" : "fdsa"); упрощено до $asdf = (1 OR (true ? "asdf" : "fdsa"));, таким образом $asdf = 1 OR "asdf" (который действительно приведен, как упоминалось выше). Это незначительно и даже немного избыточно, но может помочь людям, которые в этом не разбираются. (РЕДАКТИРОВАТЬ: Я немного устарел с этим, поэтому, если я что-то неправильно понял, извините. РЕДАКТИРОВАТЬ №2: Я только что увидел, что ответ vural объясняет это.) - person Max; 16.08.2015

Здесь:

// use () - result in brackets assigned to $asdf
$asdf = (1 OR true ? "asdf" : "fdsa");
var_dump($asdf); // print true

И тут:

// = has higher precedence so $asfd equals 1 
// and it doesn't matter what is the result of ternary operator
$asdf = 1 OR true ? "asdf" : "fdsa";
// line equals to 
($asdf = 1) OR (true ? "asdf" : "fdsa");
// so $asdf is always 1 here
var_dump($asdf); // print 1
person u_mulder    schedule 14.08.2015

$ asdf = (1 ИЛИ правда? "asdf": "fdsa");

Это равно (1 OR (true ? "asdf" : "fdsa"));

И это равно (1 OR "asdf");

А это равно true;

1 ИЛИ "asdf" не равно (1 ИЛИ "asdf"). Если вы не используете скобки, выражение после оператора OR больше не имеет значения. Вы присвоили первому элементу значение. Но если вы используете скобки, первым элементом будет инструкция в скобках.

person vural    schedule 14.08.2015
comment
Привет, (1 OR asdf) вернет bool (true). - person vural; 14.08.2015
comment
Это не объясняет разницу между третьим и четвертым примером. - person Volvox; 14.08.2015
comment
Привет, Volvox, 1 OR asdf не равно (1 OR asdf). Если вы используете скобки, PHP вернет логическое значение, как вы увидите на странице логических операторов в PHP php.net/manual/en/language.operators.logical.php. - person vural; 14.08.2015
comment
Но почему он вернет int, если не использовать скобки? - person u_mulder; 14.08.2015
comment
@u_mulder; Оператор после оператора OR больше не важен. Вы присвоили первому элементу значение. Но если вы используете скобки, первым элементом будет выражение в скобках. - person vural; 14.08.2015
comment
Но почему вы не объяснили это в своем ответе? - person u_mulder; 14.08.2015
comment
Это была моя вина, я изменил свой ответ на более подробный. Спасибо за проявленный интерес. - person vural; 14.08.2015