17

Today, I was open-mouthed by the following:

$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

Ok, the last does not surprise me much, but the third? Can anyone explain?

Pang
  • 9,564
  • 146
  • 81
  • 122
Stefano
  • 297
  • 2
  • 4
  • 15

3 Answers3

15

This is all about operator precedence and their associativity

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

or has lower precendence than = that is why it will be executed first

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

will be someting like

($asdf = 1) or true ? :"asdf" : "fdsa" that is why it will print 1.

$a or $b check whether $a or $b is true if $a is true then it is returned and it does not even go to check $b

In third case

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

() has higher precedence than = so it will be executed before assignment.

To prove it

change OR to || which has higher precendence than =

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

var_dump($asdf); // print asdf
Robert
  • 19,800
  • 5
  • 55
  • 85
  • 2
    But how the hell does `(1 OR true ? "asdf" : "fdsa")` evaluate to `true`, not `"asdf"`? – Bergi Aug 14 '15 at 09:41
  • 1
    because (1 OR "asdf") is true :P – Robert Aug 14 '15 at 09:43
  • 2
    Ah, it casts the result to boolean. [PHP, not something else](https://en.wikipedia.org/wiki/Short-circuit_evaluation#Support_in_common_programming_languages). – Bergi Aug 14 '15 at 09:44
  • Yes it is logical expression. – Robert Aug 14 '15 at 09:45
  • Good answer, but aren't you assuming that the reader knows that `?` has higher precedence than `OR`? It feels like you missed that part of the explanation, where `$asdf = (1 OR true ? "asdf" : "fdsa");` is simplified to `$asdf = (1 OR (true ? "asdf" : "fdsa"));`, thus `$asdf = 1 OR "asdf"` (which indeed is casted, as mentioned above). It's minor, and even a bit reduntant, but it may help people who are completely new to this. (EDIT: I'm a bit rusty with this, so if I've misunderstood something, excuse me. EDIT #2: I just saw that vural's answer explains this.) – Max Aug 16 '15 at 15:03
3

Here:

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

And here:

// = 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
u_mulder
  • 54,101
  • 5
  • 48
  • 64
2

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

It equals (1 OR (true ? "asdf" : "fdsa"));

And it equals (1 OR "asdf");

And this equals true;

1 OR "asdf" is not equal (1 OR "asdf"). If you don't use brackets, the statement after OR operator is not important anymore. You assigned the first element as value. But if you use brackets, the first element will be statement in brackets

vural
  • 381
  • 2
  • 11
  • Hi, (1 OR "asdf") will return bool(true). – vural Aug 14 '15 at 07:38
  • 5
    This does not explain difference between third and fourth example. – Volvox Aug 14 '15 at 07:38
  • Hi Volvox, 1 OR "asdf" is not equal (1 OR "asdf"). If you use brackets, PHP return boolean as you will see in "Logical operators" page in PHP http://php.net/manual/en/language.operators.logical.php. – vural Aug 14 '15 at 07:42
  • 1
    But why it will return `int` when not using brackets? – u_mulder Aug 14 '15 at 07:50
  • @u_mulder; The statement after OR operator is not important anymore. You assigned the first element as value. But if you use brackets, the first element will be statement in brackets. – vural Aug 14 '15 at 07:57
  • 2
    But why didn't you explain it in your answer? – u_mulder Aug 14 '15 at 08:04
  • That was my fault, I changed my answer as more detailed. Thanks your interest. – vural Aug 14 '15 at 08:12