The PHP logo and the words 'PHP 8.4'
September 26, 2024

What’s New in PHP 8.4: Features, Changes, and Deprecations

PHP Development

The PHP 8.4 release date is approaching fast, and PHP teams across the globe are considering when or if they will upgrade once it becomes available. As this release includes several exciting new features and a few key deprecations, teams will need to assess how the changes in PHP 8.4 impact their applications and plans for upgrading or migration.

In this blog, I walk through what you need to know about PHP 8.4 before it releases. I discuss critical dates to keep in mind, explore new features, outline deprecations, and discuss migration considerations for teams building a migration plan.

Back to top

PHP 8.4 Release Date Overview

PHP 8.4 is in active development and has recently reached the feature freeze state in preparation for an initial release candidate. All proposals for feature additions and changes have already been accepted and approved by the PHP internals team.

The PHP release cycle changed in June due to an RFC passed earlier this year. The new policy starts the release cycle by a month later and reduces the release candidate phase from six to four releases in order to continue hitting the same annual release date. This was done to give more time for feature discussion, and due to a recognition that the additional two release candidates have historically had few, if any, changes.

Additionally, the lifecycle of releases has been extended in two ways. First, instead of hitting end of life (EOL) on an anniversary of the release, the EOL date is now December 31 in all cases. Second, all releases, starting with PHP 8.1, will now receive both two years of active support, including both security and bug fixes, and two years of security-only support, for a total of four years (plus a little over a month).

PHP 8.4 Release Date

The PHP 8.4 release date is scheduled for November 21, 2024.

PHP 8.4 Release Date Timeline

As discussed above, PHP 8.4 follows a newly condensed timeline compared to previous versions. At time of publication, PHP 8.4 has progressed through Beta Release and is on track to proceed to Release Candidate 1, as noted in the table below.

DateMilestone
July 4, 2024Alpha Release 1
July 18, 2024Alpha Release 2
August 1, 2024Alpha Release 3 (Skipped)
August 1, 2024Alpha Release 4
August 13, 2024Feature Freeze
August 15, 2024Beta Release 1 (Skipped)
August 15, 2024Beta Release 2 (Skipped)
August 15, 2024Beta Release 3
August 29, 2024Beta Release 4
September 12, 2024Beta Release 5
September 26, 2024Release Candidate 1
October 10, 2024Release Candidate 2
October 24, 2024Release Candidate 3
November 7, 2024Release Candidate 4
November 21, 2024General Availability Release

Stay Up-to-Date With the Latest PHP Versions

PHP sets an aggressive release cycle, and understanding how versions are released, developed, and changed can be a challenge. Use this collection of resources to learn more about how using current PHP versions keeps your apps secure and supported.

Your Guide to PHP Versions

Back to top

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 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 feature is incredibly powerful and will have a lot of interesting use cases. We will likely cover it in more detail in a later blog post. 

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! 

New Array Find Functions

Not everything in PHP 8.4 has to do with its object model; this 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:

For a complete list, visit the list of PHP 8.4 accepted RFCs.

Back to top

PHP 8.4 Deprecations

Alongside the new PHP 8.4 features, several deprecations will likewise go into effect, including implicit nullable types, deprecation of GET/POST sessions, and several other changes. Below, I break down the most important changes 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. 

Back to top

Considerations for Upgrading or Migrating to PHP 8.4

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. 

Back to top

Final Thoughts

Another option for planning for PHP 8.4 is to consider engaging with a third-party consultant or organization, such as Zend by Perforce, to assist you. 

Zend solves the hardest problems in PHP, and we have been assisting teams with their upgrades, migrations, and other PHP challenges for decades. From offering Long Term Support for EOL PHP versions to providing professional services to ease PHP management, our team is in your corner as you prepare for PHP 8.4.

Make Our PHP Experts Your Experts

Zend PHP Long Term Support and Migration Services are designed to help you make the most of your PHP applications. Discover how we can support your mission-critical apps today.

SEE PHP LTS Options  Explore Migration Services

Additional Resources

Back to top