Last active
May 24, 2020 13:50
-
-
Save jasny/cf05c63fd968bed008caec5ec84268d9 to your computer and use it in GitHub Desktop.
PHP comparison gotchas
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* `a > b > c > a` should always result in false. | |
*/ | |
function all_greater($a, $b, $c) | |
{ | |
return ($a > $b) && ($b > $c) && ($c > $a); | |
} | |
// Fails due to type juggling. | |
assert(!all_greater('42', 10, '9 eur')); | |
/** | |
* if (a == b) and (a == c) then (b == c) should be true. | |
*/ | |
function equality($a, $b, $c) | |
{ | |
return ($a == $b) && ($a == $c) xor ($b != $c); | |
} | |
// Fails due to type juggling. | |
assert(equality(10, '10', '10 eur')); | |
/** | |
* `a > b > a` should always result in false. | |
*/ | |
function both_greater($a, $b) | |
{ | |
return ($a > $b) && ($a < $b); | |
} | |
// Fails because it's based on the order of the 'smallest' operator. | |
assert(!both_greater(['x' => 1, 'y' => 2], ['y' => 1, 'x' => 2])); | |
/** | |
* `a <> b` == (`a < b` || `a > b`) should always return in true. | |
*/ | |
function equal_or_not($a, $b) | |
{ | |
return ($a <> $b) == (($a < $b) || ($a > $b)); | |
} | |
// Fails because `>` and `<` always result in false with key mismatch. | |
assert(equal_or_not(['x' => 0], ['y' => 1])); | |
/** | |
* Sorting shout be stable. | |
* The initial order should not affect sorting. | |
*/ | |
function sorted(array $arr) | |
{ | |
usort($arr, fn($x, $y) => ($x <=> $y)); | |
return $arr; | |
} | |
// Fails due to type juggling. | |
assert(sorted(['42', 10, '9 eur']) === sorted(['42', 10, '9 eur'])); | |
// Fails due to numeric comparison of strings. | |
assert(sorted(['100', '5 eur', '62']) === sorted(['100', '62', '5 eur'])); | |
/** | |
* Identical and equal on two strings should be the same. | |
*/ | |
function string_equality(string $a, string $b) | |
{ | |
return ($a == $b) == ($a === $b); | |
} | |
// Fails because hexadecimal values may be interpreted as scientific notation. | |
assert(string_equality('880000', '8800e2')); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment