PHP 7: Maintaining and Upgrading Legacy Apps · Upgrading from PHP 7 to PHP 8

PHP 8.0 Breaking Changes That Bite

String-number comparisons, stricter errors, removed functions and more.

The PHP 8.0 changes that most often break legacy code: string-to-number comparison (0 == 'abc' is now false), many warnings became TypeError/ValueError exceptions (e.g., strlen([]), invalid arguments to internal functions), undefined variables/array keys went from notices to warnings, each(), create_function() and the (real) cast were removed, unparenthesized nested ternaries are errors, and resources became objects (e.g., curl_init() returns CurlHandle, so is_resource() checks fail).

<?php
var_dump(0 == 'abc');        // PHP 7: true   PHP 8: false
var_dump('1' == '01');       // true in both (numeric strings)
var_dump(null == false);     // true in both

$ch = curl_init();
if (!is_resource($ch)) { /* PHP 8: always true → bug! */ }
if ($ch === false) { /* correct check */ }

// Removed: each(), create_function(), money_format(), $php_errormsg
// PHP 4-style constructors (a method named after the class) are no longer constructors

Common pitfalls

  • is_resource() checks on cURL, GD, XML handles returning false in PHP 8.
  • Code relying on 0 == 'string' being true (e.g., in_array without strict).
  • Old-style constructors named after the class (PHP 4 style) no longer act as constructors.

Key points

  • String-number comparison changed
  • Warnings → exceptions in internal functions
  • Resources → objects: fix is_resource checks

Further reading: PHP manual: PHP 8.0 backward incompatible changes

Practice questions

Why might in_array(0, ['a', 'b']) behave differently on PHP 8?

Answer

In PHP 7, 0 == 'a' was true (the string was cast to 0), so it returned true. In PHP 8, non-numeric strings are compared as strings, so it returns false. Use strict in_array(..., true).

What breaks with is_resource(curl_init()) in PHP 8?

Answer

curl_init() returns a CurlHandle object, not a resource, so is_resource() returns false. Check === false instead.

Open in the app to mark lessons complete, take notes and track your progress.