
PHP 8.0 to 8.4 New Features Recap
Published on Jan 15, 2025
PHP has evolved significantly since version 8.0, introducing features that enhance performance, developer experience, and code readability. Let's say it has very important features that maybe not everyone aware of, or some features we didn't yet get used to it. This is why I thought to refresh our information and review all PHP 8 important features once again with some simple examples.
PHP 8.0
Named Arguments
PHP 8.0 introduced named arguments, allowing developers to pass values to a function by specifying the parameter name:
function process_order($id, $status, $notify = true) { // Implementation } // Using named arguments process_order(status: "completed", id: 100, notify: false);
As mentioned in the PHP Documentation This feature allowing arguments to be order independent, self documented and optional parameters can be skipped.
Constructor Property Promotion
A more concise way to define and initialize class properties:
// Before PHP 8.0 class User { private string $name; private string $email; public function __construct(string $name, string $email) { $this->name = $name; $this->email = $email; } } // With PHP 8.0 class User { public function __construct( private string $name, private string $email, ) {} }
Union Types
The ability to specify multiple allowed types for properties, parameters, and return values:
public function process(int|float $number): string|array { // Implementation }
Match Expression
A more powerful and safer alternative to switch statements:
return match ($status) { 200 => "success", 300 => "redirect", 400 => "not found", 500 => "server error", default => "unknown status", };
Nullsafe Operator
Safe method and property access when dealing with null values:
// Before PHP 8.0 $country = null; if ($session !== null) { $user = $session->user; if ($user !== null) { $address = $user->getAddress(); if ($address !== null) { $country = $address->country; } } } // With PHP 8.0 $country = $session?->user?->getAddress()?->country;
PHP 8.1
Enums
PHP8.1 introduced First-class support for enumerations:
// Before PHP 8.1 const STATUS_ACTIVE = 'Active'; const STATUS_INACTIVE = 'Inactive'; // With PHP 8.1 enum Status { case Active; case Inactive; }
There is a lot we can talk about for explaining Enums for the above example this is the basic usage and it could be accessed like this:
$status = Status::Active; echo $status->name; // This will print Active
We could also have backed Enum when we want to represent a value from database this will be useful
// Backed Enum enum Status: int { case Active = 1; case Inactive = 2; } $status = Status::Active; echo $status->value; // This will print 1
For Backed Enums we will have available value property alongside with the name property. If you want to explore more about Enums check it out in PHP Documentation
Readonly Properties
Properties that can only be set once, during initialization:
class User { public readonly string $id; public function __construct(string $id) { $this->id = $id; } }
From PHP Documentation: "Readonly properties cannot be changed after initialization, i.e. after a value is assigned to them.
They are a great way to model value objects and data-transfer objects."
PHP 8.2
Readonly Classes
Entire classes can be marked as readonly:
readonly class User { public string $name; public string $email; }
From PHP Documentation: "Marking a class as readonly will add the readonly modifier to every declared property, and prevent the creation of dynamic properties."
Null, False, and True Stand-alone Types
Allowing null, false and true as stand-alone types:
// Before PHP 8.2 function setFlag(true $value) { // Only accepts true } // With PHP 8.2 function setFlag(bool $value) {}
Trait Constants
With PHP 8.2 you can define constants in a trait but you cannot access them through the name of the trait, but through the class that uses the trait.
trait A { public const GREETING = 'hello'; } class B { use A; } var_dump(B::GREETING); // hello var_dump(A::GREETING); // Error
Deprecate Dynamic Properties
I think we need to highlight this change as well, because it's now produces deprecated notice so we need to get used to the new syntax.
class User { public $name; } $user = new User(); $user->last_name = 'Doe'; // Deprecated notice (This was okay before PHP 8.2) $user = new stdClass(); $user->last_name = 'Doe'; // Still allowed
Unless the class opts in by using the #[\AllowDynamicProperties] otherwise we should not use dynamic properties anymore.
PHP 8.3
Typed Class Constants
Ability to specify types for class constants:
class Configuration { public const string DATABASE_NAME = "my_app"; public const int MAX_CONNECTIONS = 100; }
Dynamic Class Constant Fetch
Ability to fetch class constants dynamically:
class Config { public const ERROR_LEVEL = 'error'; } $level = 'ERROR_LEVEL'; echo Config::{$level}; // outputs: error
New json_validate Function
A new function to check if string is a valid json, more efficient than json_decode().
// With PHP 8.3 var_dump(json_validate('{ "test": { "foo": "bar" } }')); // true // Before PHP 8.3 function json_validate(string $string): bool { json_decode($string); return json_last_error() === JSON_ERROR_NONE; } var_dump(json_validate('{ "test": { "foo": "bar" } }')); // true
PHP 8.4
Property Hooks
Introducing a short way of setting and getting variables that may include some modifications, this is a nice example from PHP Docs:
class User implements Named { private bool $isModified = false; public function __construct(private string $first, private string $last) {} public string $fullName { // Override the "read" action with arbitrary logic. get => $this->first . " " . $this->last; // Override the "write" action with arbitrary logic. set { [$this->first, $this->last] = explode(' ', $value, 2); $this->isModified = true; } } }
New Array Functions
New functions array_find(), array_find_key(), array_any(), and array_all() are available
Those functions are discussed with more detailed examples in this article
Conclusion
In addition to the previous discussed features there are other features and improvements, but I only mentioned what caught my eye and what could be handy for a developer daily use.
Besides also a huge improvement in performance PHP 8 introduced JIT (Just in Time) Compiler and some concurrency techniques like fibers (this may not be for end users), but in general there is been many changes in the last releases. We might have a deep look on JIT in future topic and see how it works.