As I learned Xor should return false when two variable are true
But I tried it and it doesn't work!
$n1 = true;
$n2 = true;
$res = $n1 xor $n2;
echo var_dump($res);
This because of PHP Operator Precedence. Following example is correct
$n1 = true;
$n2 = true;
$res = ($n1 xor $n2);
echo var_dump($res); // bool(false)
Priority. Your third statement is evaluated as
($res = $n1) xor $n2;
I.e. first the assignment happens, and $res
becomes what $n1
is (i.e. true
); the assignment evaluates as the value being assigned, so as the next step true xor $n2
is evaluated, producing false
; but this value is not stored or used in any way, and is discarded. Basically, your code is equal to
$n1 = true;
$n2 = true;
$res = $n1;
$res xor $n2; // useless
echo var_dump($res);
To expound a bit more, note that there are two sets of logical operators, where the only difference is how tightly they bind. and
, or
and xor
bind very loosely, while their counterparts &&
and ||
bind tighter. Unfortunately, there is no tight binding counterpart for xor
. These operators have been brought over from Perl, where a common idiom was to use the loosely-binding operators for flow control:
$f = doSomethingThatMightBeFalsy() or die("I failed at my task");
which will assign $f
, and if that value ends up being falsy, die. This is distinct from
$f = doSomethingThatMightBeFalsy() || die("I fail evrytym :(");
tl;dr: As Akam already wrote, you should explicitly use parentheses to make xor
bind tighter than the assignment.