Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
PHP comparison gotchas
<?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