PHP’s comparison operators deviate from the computer-scientific definitions in several ways:
In order to constitute an equivalence relation == has to be reflexive, symmetric and transitive:
-
PHP’s
==operator is not reflexive, i.e.$a == $ais not always true:var_dump(NAN == NAN); // bool(false)Note: The fact that any comparison involving
NANis alwaysfalseis not specific to PHP. It is mandated by the IEEE 754 Standard for Floating-Point Arithmetic (more info). -
PHP’s
==operator is symmetric, i.e.$a == $band$b == $aare always the same. -
PHP’s
==operator is not transitive, i.e. from$a == $band$b == $cdoes not follows$a == $c:var_dump(true == "a"); // bool(true) var_dump("a" == 0); // bool(true) var_dump(true == 0); // bool(false)
In order to constitute a partial order <=/>= has to be reflexive, anti-symmetric and transitive:
-
PHP’s
<=operator is not reflexive, i.e.$a <= $ais not always true (Example same as for==). -
PHP’s
<=operator is not anti-symmetric, i.e. from$a <= $band$b <= $adoes not follow$a == $b:var_dump(NAN <= "foo"); // bool(true) var_dump("foo" <= NAN); // bool(true) var_dump(NAN == "foo"); // bool(false) -
PHP’s
<=operator is not transitive, i.e. from$a <= $band$b <= $cdoes not follow$a <= $c(Example same as for==). -
Extra: PHP’s
<=operator is not total, i.e. both$a <= $band$b <= $acan be false:var_dump(new stdClass <= new DateTime); // bool(false) var_dump(new DateTime <= new stdClass); // bool(false)
In order to constitute a strict partial order </> has to be irreflexive, asymmetric and transitive:
-
PHP’s
<operator is irreflexive, i.e.$a < $ais never true. Note that this is true only as of PHP 5.4. PreviouslyINF < INFevaluated totrue. -
PHP’s
<operator is not asymmetric, i.e. from$a < $bdoes not follow!($b < $a)(Example same as for<=not being anti-symmetric). -
PHP’s
<operator is not transitive, i.e. from$a < $band$b < $cdoes not follow$a < $c:var_dump(-INF < 0); // bool(true) var_dump(0 < TRUE); // bool(true) var_dump(-INF < TRUE); // bool(false) -
Extra: PHP’s
<operator is not trichotomous, i.e. all of$a < $b,$b < $aand$a == $bcan be false (Example same as for<=not being total). -
Extra: PHP’s
<operator can be circular, i.e. it is possible that$a < $b,$b < $cand$c < $a:var_dump(INF < []); // bool(true) var_dump([] < new stdClass); // bool(true) var_dump(new stdClass < INF); // bool(true)Note: The above example throws a “Object of class stdClass could not be converted to double” notice.
You can find a few nice graphs for PHP’s comparison operators on PHP Sadness 52 – Comparison operators.
As a last note, I want to point out that there are two equalities that PHP does guarantee (unlike pretty much everything else). These two always hold, simply because the compiler reduces one to the other:
($a > $b) == ($b < $a)
($a >= $b) == ($b <= $a)