I have if ($input == 0) returning true for the string 'abc' in older code and I am not sure it behaves the same on PHP 8. What exactly changed and when should I use === ?
DEV3 Developer Forum
What is the difference between == and === in PHP 8?
Every post is reviewed first. Usually reviewed within 24 hours.
1 reply
== compares values after type juggling. === compares value and type with no conversion.
The PHP 8 change
PHP 8 changed string and number comparison. Before 8.0, 0 == "abc" was true because "abc" was cast to 0. Since 8.0, if the string is not numeric, the number is cast to a string and compared as strings, so:
var_dump(0 == "abc"); // PHP 7: true, PHP 8: false
var_dump("1" == "01"); // true (both numeric strings)
var_dump(100 == "1e2"); // true (numeric string)
var_dump(null == false); // true
var_dump([] == false); // true
var_dump("0" == false); // true
var_dump("abc" == 0); // false in PHP 8
Numeric strings with trailing whitespace are now also treated as numeric ("123 " == 123 is true).
Use === by default
if ($status === 'active') {}
if (in_array($id, $allowed, true)) {} // third argument = strict
if (array_search('x', $list, true) !== false) {}
switch (true) {} // or use match
in_array, array_search and array_keys are loose by default, so a classic bug is in_array('abc', [0]) returning true in PHP 7.
Security note: loose comparison of hashes can be exploited ("magic hashes": "0e123" == "0e456" is true because both are numeric strings in scientific notation). Always compare tokens and hashes with hash_equals() and passwords with password_verify().
Useful related tools
matchuses strict comparison and throwsUnhandledMatchErrorif nothing matches.- The spaceship operator
<=>still uses loose comparison rules. - Add
declare(strict_types=1);for strict scalar type checks on function arguments (it does not change==).
Pitfall: "abc" == 0 fixed in 8.0 may have been hiding in legacy code, so test upgrades with E_ALL and static analysis (PHPStan or Psalm).