As mentioned in previous post What’s new in PHP 8 – Part 1(New features) : this is a major update and thus there will be breaking changes. The best thing to do is take a look at the full list of breaking changes over at the UPGRADING document.
Many of these breaking changes have been deprecated in previous 7.* versions though, so if you’ve been staying up-to-date over the years, it shouldn’t be all that hard to upgrade to PHP 8.
Consistent type errors rfc
User-defined functions in PHP will already throw TypeError
, but internal functions did not, they rather emitted warnings and returned null
. As of PHP 8 the behaviour of internal functions have been made consistent.
Reclassified engine warnings rfc
Lots of errors that previously only triggered warnings or notices, have been converted to proper errors. The following warnings were changed.
- Undefined variable:
Error
exception instead of notice - Undefined array index: warning instead of notice
- Division by zero:
DivisionByZeroError
exception instead of warning - Attempt to increment/decrement property ‘%s’ of non-object:
Error
exception instead of warning - Attempt to modify property ‘%s’ of non-object:
Error
exception instead of warning - Attempt to assign property ‘%s’ of non-object:
Error
exception instead of warning - Creating default object from empty value:
Error
exception instead of warning - Trying to get property ‘%s’ of non-object: warning instead of notice
- Undefined property: %s::$%s: warning instead of notice
- Cannot add element to the array as the next element is already occupied:
Error
exception instead of warning - Cannot unset offset in a non-array variable:
Error
exception instead of warning - Cannot use a scalar value as an array:
Error
exception instead of warning - Only arrays and
Traversables
can be unpacked:TypeError
exception instead of warning - Invalid argument supplied for foreach():
TypeError
exception instead of warning - Illegal offset type:
TypeError
exception instead of warning - Illegal offset type in isset or empty:
TypeError
exception instead of warning - Illegal offset type in unset:
TypeError
exception instead of warning - Array to string conversion: warning instead of notice
- Resource ID#%d used as offset, casting to integer (%d): warning instead of notice
- String offset cast occurred: warning instead of notice
- Uninitialized string offset: %d: warning instead of notice
- Cannot assign an empty string to a string offset:
Error
exception instead of warning - Supplied resource is not a valid stream resource:
TypeError
exception instead of warning
The @ operator no longer silences fatal errors
It’s possible that this change might reveal errors that again were hidden before PHP 8. Make sure to set display_errors=Off
on your production servers!
Default error reporting level
It’s now E_ALL
instead of everything but E_NOTICE
and E_DEPRECATED
. This means that many errors might pop up which were previously silently ignored, though probably already existent before PHP 8.
Default PDO error mode rfc
From the RFC: The current default error mode for PDO is silent. This means that when an SQL error occurs, no errors or warnings may be emitted and no exceptions thrown unless the developer implements their own explicit error handling.
This RFC changes the default error will change to PDO::ERRMODE_EXCEPTION
in PHP 8.
Concatenation precedence rfc
While already deprecated in PHP 7.4, this change is now taken into effect. If you’d write something like this:
echo "sum: " . $a + $b;
PHP would previously interpret it like this:
echo ("sum: " . $a) + $b;
PHP 8 will make it so that it’s interpreted like this:
echo "sum: " . ($a + $b);
Stricter type checks for arithmetic and bitwise operators rfc
Before PHP 8, it was possible to apply arithmetic or bitwise operators on arrays, resources or objects. This isn’t possible anymore, and will throw a TypeError
:
[] % [42];
$object + 4;
Namespaced names being a single token rfc
PHP used to interpret each part of a namespace (separated by a backslash \
) as a sequence of tokens. This RFC changed that behaviour, meaning reserved names can now be used in namespaces.
Saner numeric strings rfc
PHP’s type system tries to do a lot of smart things when it encounters numbers in strings. This RFC makes that behaviour more consistent and clear.
Saner string to number comparisons rfc
This RFC fixes the very strange case in PHP where 0 == "foo"
results in true
. There are some other edge cases like that one, and this RFC fixes them.
Reflection changes
A few reflection methods have been deprecated:
ReflectionFunction::isDisabled()
ReflectionParameter::getClass()
ReflectionParameter::isCallable()
You should now use ReflectionType
to get information about a parameter’s type:
$reflectionParameter->getType()->allowsNull();
If the type is a single type, ReflectionParameter::getType()
returns an instance of ReflectionNamedType
, which you can get its name from and whether it’s built-in:
$reflectionParameter->getType()->getName();
$reflectionParameter->getType()->isBuiltin();
If the type is a union type however, you’ll get an instance of ReflectionUnionType
, which can give you an array of ReflectionNamedType
like so:
$reflectionParameter->getType()->getTypes();
Checking whether a type is a union or not can be done with an instanceof
check:
if ($reflectionParameter->getType() instanceof ReflectionNamedType) {
// It's a single type
}
if ($reflectionParameter->getType() instanceof ReflectionUnionType) {
// It's a union type
}
Next up, three method signatures of reflection classes have been changed:
ReflectionClass::newInstance($args);
ReflectionFunction::invoke($args);
ReflectionMethod::invoke($object, $args);
Have now become:
ReflectionClass::newInstance(...$args);
ReflectionFunction::invoke(...$args);
ReflectionMethod::invoke($object, ...$args);
The upgrading guide specifies that if you extend these classes, and still want to support both PHP 7 and PHP 8, the following signatures are allowed:
ReflectionClass::newInstance($arg = null, ...$args);
ReflectionFunction::invoke($arg = null, ...$args);
ReflectionMethod::invoke($object, $arg = null, ...$args);
Stable sorting rfc
Before PHP 8, sorting algorithms were unstable. This means that the order of equal elements wasn’t guaranteed. PHP 8 changes the behaviour of all sorting functions to stable sorting.
Fatal error for incompatible method signatures rfc
From the RFC: Inheritance errors due to incompatible method signatures currently either throw a fatal error or a warning depending on the cause of the error and the inheritance hierarchy.
Other deprecations and changes
During the PHP 7.* development, several deprecations were added that are now finalised in PHP 8.
- Deprecations in PHP 7.2
- Deprecations in PHP 7.3
- Deprecations in PHP 7.4
- Locale-independent float to string cast