
PHP 8.4, released on November 21, 2024, introduces several significant features and changes aimed at enhancing code quality, performance, and developer experience. Here's an overview of the key updates:
1. Property Hooks
Property hooks allow developers to define custom behavior for property access and modification directly within the class, eliminating the need for traditional getters and setters. This feature simplifies class design and enhances maintainability. citeturn0search0
2. Asymmetric Visibility
PHP 8.4 introduces asymmetric visibility, enabling different visibility levels for reading and writing properties. This means a property can be publicly readable but privately writable, offering greater flexibility in property access control. citeturn0search5
3. New Array Functions
Several new array functions have been added to PHP 8.4 to improve array manipulation:
array_find()
: Returns the value of the first element that satisfies a given condition.array_find_key()
: Returns the key of the first element that satisfies a given condition.array_any()
: Checks if any element in the array satisfies a given condition.array_all()
: Checks if all elements in the array satisfy a given condition.
These functions enhance the expressiveness and efficiency of array operations. citeturn0search1
4. Simplified Object Instantiation
PHP 8.4 allows method chaining on object instantiation without the need for additional parentheses. This results in cleaner and more readable code. citeturn0search2
5. HTML5 Support
The DomHTMLDocument
class has been introduced to provide native support for parsing and manipulating HTML5 documents, enhancing PHP's capabilities in web development. citeturn0search6
6. Deprecations and Removals
PHP 8.4 deprecates several features to encourage better coding practices and prepare for future versions:
- Implicitly nullable parameter declarations are deprecated.
- The
E_STRICT
constant is deprecated. - Calling
session_set_save_handler()
with more than two arguments is deprecated. - The
#[\Deprecated]
attribute is introduced to mark features for deprecation.
Additionally, the Pspell, IMAP, OCI8, and PDO-OCI extensions have been moved from PHP Core to PECL. citeturn0search1
These changes aim to streamline the language and encourage developers to adopt more robust and modern coding practices.
For a comprehensive list of all changes, refer to the official PHP 8.4 release notes. citeturn0search7
PHP 8.4 Release Date Timeline
As discussed above, PHP 8.4 follows a newly condensed timeline compared to previous versions. See the table below for further PHP 8.4 release date details.
Date | Milestone |
July 4, 2024 | Alpha Release 1 |
July 18, 2024 | Alpha Release 2 |
August 1, 2024 | Alpha Release 3 (Skipped) |
August 1, 2024 | Alpha Release 4 |
August 13, 2024 | Feature Freeze |
August 15, 2024 | Beta Release 1 (Skipped) |
August 15, 2024 | Beta Release 2 (Skipped) |
August 15, 2024 | Beta Release 3 |
August 29, 2024 | Beta Release 4 |
September 12, 2024 | Beta Release 5 |
September 26, 2024 | Release Candidate 1 |
October 10, 2024 | Release Candidate 2 |
October 24, 2024 | Release Candidate 3 |
November 7, 2024 | Release Candidate 4 |
November 21, 2024 | General Availability Release |
PHP 8.4 Features
PHP 8.4 introduces a number of new features and changes aiming to simplify PHP usage and solve a few common developer challenges. In this section, I will discuss a few of the most prominent PHP 8.4 features:
- Property Hooks
- Asymmetric Visibility
- New Find Array Functions
- MyClass()->method() Without Parentheses
- JIT Changes
- HTML5 Support
- Other PHP 8.4 features to watch
Property Hooks
Properties in PHP objects have raised issues for PHP developers since they were initially provided in the language. Property visibility has helped in many cases, as it allows developers to enforce value validations. The ability to provide property types starting in PHP 7 has helped this even more, but the fact that validation by necessity must happen via a method has led to a lot of boilerplate in the the forms of getters and setters, or abuse of the __get and __set magic methods.
The ability to define readonly properties in PHP 8 solves a lot of problems for many developers as they can guard values via the constructor and still provide fully typed properties for direct access. However, if you want a mutable structure, this only goes so far.
Property Hooks in PHP 8.4 finally provide a robust feature for working with PHP class properties. Properties can now optionally define one or more hooks, currently restricted to "get" and "set", that allow you to hook into the lifecycle of the property. Each hook is a short callable that allows you to perform some logic when the operation is called (e.g., when retrieving a property value, or setting a property value). As a short example from the RFC:
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;
}
}
}
In this example, the "$fullName" property defines both a "set" and a "get" hook. Further, it’s backed not by a value, but by other properties. When you retrieve the value, it returns the product of concatenating the "$first" and "$last" properties. When setting the value, it sets those values by exploding the string provided into two segments, and then sets an internal property indicating the value was modified.
Another feature that Property Hooks enables is the ability to define properties on interfaces, as between the ability to provide type information and the ability to define operations, there’s now a solid reason to allow them.
This PHP 8.4 feature is incredibly powerful and will have a lot of interesting use cases. Visit our Guide to PHP 8.4 Property Hooks for an in-depth examination.
Asymmetric Visibility
As noted in the previous section, object properties have posed challenges that PHP developers have needed to work around for many years. We also mentioned "readonly" properties as helping solve some problems seen with properties: how do we ensure that the value in the property is always valid?
One issue with "readonly" for properties is that while it helps enforce immutability, there are many, many cases where immutability may not be desired and where the object should largely resemble some sort of data structure that is always in a valid state.
The Asymmetric Visibility proposal aims to solve some of those problems. The idea behind it is to allow defining differing visibility for different operations on a property. As an example, you could indicate that you want to allow public read access to a property, but only allow modifications to it internally:
public private(set) string $bar = 'baz';
This feature works in conjunction with the changes introduced with Property Hooks, including the ability to define visibility in interfaces. Between these two features, there’s a ton of new power when writing data structures using objects!
For an in-depth look at asymmetric visibility, check out this blog: Asymmetric Visibility in PHP 8.4: What It Means for PHP Teams.
New Array Find Functions
Not everything in PHP 8.4 has to do with its object model; the PHP 8.4 release also introduces some useful new array functions, aimed at more succinctly determining if values are found in arrays. These include:
- array_find
- array_find_key
- array_any
- array_all
Each accepts two arguments, the array to operate on, and a callback to invoke for each item in the array. If the callback returns "true" at any point, it will stop searching and return immediately — except in the case of array_all(), which only returns true if all values in the array are validated by the callback.
MyClass()->method() Without Parentheses
A not uncommon pattern in PHP is to instantiate a class instance and immediately access either a property or a method, without requiring the instance any further. This looks something like this:
$request = (new Request())->withMethod('GET')->withUri('/hello-world');
Note that when instantiating the class, we have to wrap that in parentheses; this is a requirement of the PHP engine at this time, and it makes this type of usage unwieldy.
PHP 8.4 now allows you to omit those parentheses, giving a more natural usage that's easier to remember:
$request = new Request()->withMethod('GET')->withUri('/hello-world');
JIT Changes
Zend's Dmitry Stogov has continued work on the Just-In-Time compiler for PHP. Last year, he brought a proposal to the internals group to replace the JIT implementation he’d previously provided with a smarter one that is backed by an Intermediate Representation engine. This work simplifies maintenance of the internal Zend Engine, as it allows separating the work done by the JIT from the parser and interpreter.
This work was done in such a way as to provide no breaking changes to users, and will simplify maintenance and feature additions for internals developers going forwards.
On-Demand Webinar: Exploring JIT Compilation in PHP 8
Join me as I discuss the level of benefit (and complexity) developers can expect in real-world PHP applications using JIT compilation in this on-demand webinar.
HTML5 Support
While HTML5 has been around for a very long time now, the DOM parser used by the PHP engine has lingered behind, only supporting HTML 4.01 features. The PHP 8.4 release rectifies that situation with comprehensive support for HTML5, via adoption of a more capable HTML5 parsing library, and new opt-in DOM classes that exist in a new PHP namespace to allow differentiation from the existing XML-oriented DOM classes.
For developers who are parsing or building HTML using the DOM extension, expect to get a huge chunk of new features and better support for HTML5 with this release!
For more information, visit the RFC.
Additional New PHP 8.4 Features
This has been a particularly busy release cycle, with a ton of new features both big and small. Some of the other new PHP 8.4 features you'll find include:
- $_POST and $_FILES now support additional HTTP verbs
- Multibyte trim functions: mb_trim(), mb_ltrim(), and mb_rtrim()
- New, clearer, rounding modes for the round() function
- Driver-specific PDO subclasses to allow access to driver-specific features
- Improved callbacks for DOM and XSL, giving the ability to use closures, first-class callables, and instance methods
- Addition of Lazy Object support, which provides low-level features for generating ghost objects, proxies, and more; these will generally be consumed by frameworks and ORMs for use with dependency injection containers and object hydration
- A new engine attribute, #[Deprecated], for marking deprecated functionality
- A number of improvements to the BCMath, GMP, and DOM extension
PHP 8.4 Deprecations
Alongside the new PHP 8.4 features, several deprecations have likewise gone into effect, including implicit nullable types, deprecation of GET/POST sessions, and several other changes. Below, I break down the most important changes in PHP 8.4 to be aware of and provide insight on how they impact your PHP applications.
Implicit Nullable Types
Before nullable types were formally introduced, they were possible by declaring a value with a default value of "null":
function foo(T1 $a, T2 $b = null, T3 $c) {}
Later, when nullable types were added, this signature could also be achieved explicitly:
function bar(T1 $a, ?T2 $b = null, T3 $c) {}
Or via a union type:
function test(T1 $a, T2|null $b = null, T3 $c) {}
In the meantime, the implicit declaration continued to work.
Starting in PHP 8.4, that implicit declaration is now deprecated, and users are prompted to update the signature to use an explicit nullable type or to declare a union type that includes "null".
Deprecation of GET/POST Sessions
Web applications often need to track user state. The accepted and recommended way to do this is to use a cookie, but PHP has also provided the ability to do this via GET and POST parameters. This is accomplished by disabling the "session.use_only_cookies" setting, due to features that existed before cookies were commonly implemented in browsers. It even went one step further by enabling a mechanism that would transparently identify a session token in any of the user’s cookies or via GET or POST parameters, via a setting called "session.use_trans_sid".
By default, "session.use_only_cookies" is enabled, and “session.use_trans_sid” is disabled. Starting in PHP 8.4, if either value is toggled differently, PHP will raise a deprecation warning. In PHP 9, these settings will no longer be available.
Other Deprecations
The above are just a couple of the deprecations that might affect you. Other RFCs implemented for PHP 8.4 also introduce deprecations, and, as usual, there was a laundry list of deprecations captured in a single RFC to cover functionality that has been flagged over the last few years.
PHP 8.4 Upgrade and Migration Considerations
We generally recommend waiting for at least one bugfix release before adopting any new feature release. While the PHP release process is lengthy and includes multiple release candidates, history has shown that not enough people test them before the general availability release is issued. Waiting also allows ecosystem QA tooling such as static analysis tooling to adapt to the new release; these tools will often help you identify potential issues with an upgrade.
Once you are ready, make sure you read through the RFCs approved, and particularly the RFC with the general list of deprecations, to see what features you use may be affected. Use static analysis tooling to test your code for compatibility, and consider seeing if tools such as Rector can help your team.
Recent Blogs

Migrating from Drupal 7 to the latest version, such as Drupal 9 or Drupal 10, is a critical step…Read more

Drupal's Plugin API has been a key part of its flexibility and extensibility, allowing…Read more

In Drupal, caching is a critical aspect of optimizing site performance, and two key concepts in…Read more