What Is New in PHP 8.0
PHP 8.0 is a major update that introduces the JIT compiler, new language features like attributes and union types, and several improvements and deprecations.
| Category | Key Changes |
|---|---|
| New Features | JIT Compiler, Attributes, Union Types, Match Expression, Constructor Property Promotion, throw Expression, Nullsafe Operator |
| Improvements | Type System Enhancements (mixed type), Stringable interface, WeakMap class, Trailing comma in parameter lists |
| Deprecations & Changes | Deprecations of several functions and features, changes to error reporting and standard library functions |
How does the JIT compiler improve performance?
The Just-In-Time (JIT) compiler is the flagship feature of PHP 8.0. It translates parts of the PHP opcode into machine code at runtime, which can then be executed directly by the CPU.
In practice, this provides significant performance benefits for long-running applications, especially in mathematical computations and large-scale applications. For typical web requests, the difference might be less dramatic but still positive.
It's enabled in the php.ini file and offers different tracing modes to suit various workloads.
What new syntax features should I start using?
Attributes
Attributes allow you to add structured metadata to classes, methods, properties, and more. They replace the docblock comments used by many frameworks for annotations.
<?php
#[Route("/api/posts", methods: ["GET"])]
class PostController
{
}
?>
Union Types
You can now declare that a parameter, property, or return value can be of multiple types. This makes the type system much more expressive.
public function foo(string|int $bar): string|int|null
Match Expression
The match expression is a more powerful and safer alternative to the switch statement. It returns a value, does strict comparisons, and requires exhaustive matching.
$result = match ($statusCode) {
200, 300 => 'OK',
404 => 'Not Found',
default => 'Unknown',
};
Nullsafe Operator
The nullsafe operator (?->) short-circuits method or property access if the object is null, preventing the need for nested null checks.
$country = $session?->user?->getAddress()?->country;
What breaking changes might break my existing code?
PHP 8.0 includes several changes that are not backward compatible. The most common issues arise from stricter type checking and promoted error levels.
- Stricter Type Checks: Parameters with union types and the new
mixedtype enforce stricter rules. - Error to Exception Conversions: Many fatal errors are now converted into
Errorexceptions, which can change how your application handles failures. - Standard Library Changes: Functions like
str_contains()are now case-sensitive, and some parameters have been swapped for consistency. - Deprecations: Functions and features that were deprecated in PHP 7.x have now been removed.
Running your code with error reporting set to E_ALL is the best way to identify these issues before upgrading.
FAQ
Is the JIT compiler enabled by default?
Yes, the JIT is enabled by default in PHP 8.0, but it is configured with a buffer size of 0, effectively turning it off. You need to configure the opcache.jit_buffer_size directive in your php.ini to a non-zero value to activate it.
What is the difference between the new 'match' and a 'switch' statement?match is an expression that returns a value, uses strict type comparisons (===), and does not require a break. It also throws an UnhandledMatchError if no arm is matched, unless a default case is provided.
How do Union Types work with inheritance?
A child class can widen the return type of a method using a union that includes the parent's return type. However, it can only narrow parameter types, not widen them, to comply with the Liskov Substitution Principle.
What replaces the old @annotations in docblocks?
You should use native PHP Attributes instead. They are declared with #[ ] syntax and are first-class citizens in the language, making them more efficient and easier to parse than docblock comments.
Why did they change the parameter order for some functions?
Functions like implode() now have a consistent parameter order. The $glue and $pieces parameters for implode() can be passed in either order for backward compatibility, but the documented order is now consistent with other functions.