A PHP editor with the post's code, each new line tagged by version: private(set) and a property hook from PHP 8.4, clone with and the pipe operator from PHP 8.5. Beside it, a calendar: 8.6 ships 19 November 2026 and PHP 8.2 security fixes end 31 December 2026.

PHP features for developers in 2026: what 8.4, 8.5 and 8.6 add, and which version brought the rest

Modern PHP is no longer enums and match. It is property hooks, the pipe operator and a support calendar that decides when your next upgrade is due.

What are the PHP features for developers that matter in October 2026?#

In October 2026 PHP 8.5 is the current stable release, PHP 8.6 is due on 19 November 2026, and the features worth adopting first arrived in 8.4 and 8.5. The php.net Supported Versions table, read on 2 October 2026, lists 8.5 with an initial release of 20 November 2025. Next, the PHP 8.6 release timetable shows the second release candidate (RC2) on 24 September 2026. A release candidate is a build that should become final unless a bug turns up. Then the same timetable puts general availability (GA, the first stable release) on 19 November 2026.

So the PHP features for developers that matter now are the recent ones. First, PHP 8.4 added property hooks, which run your own code when a property is read or written. It also added asymmetric visibility, so a property can be public to read but private to write. Then PHP 8.5 added the pipe operator and a clone function that changes properties on the copy. It also added a built-in URI extension for parsing web addresses.

The older names still come up in search: enums, readonly properties, match and named arguments. However, every one of them shipped in PHP 8.0 or 8.1, and both branches are now past their end of life. The php.net end of life table shows PHP 8.1 lost security fixes on 31 December 2025. So they sit in one lookup table further down, not in long sections.

  1. PHP 8.4

    Released 21 November 2024

    Property hooks and asymmetric visibility.

  2. PHP 8.5

    Released 20 November 2025, current

    The pipe operator, clone with and a built-in URI extension.

  3. PHP 8.6 RC2

    24 September 2026

    The second release candidate; RC1 was skipped.

  4. PHP 8.6

    GA due 19 November 2026

    The first stable PHP 8.6 release.

How long does each supported PHP version keep getting security fixes?#

PHP 8.2 stops receiving security fixes on 31 December 2026, while PHP 8.5 is covered until 31 December 2029. The rule is simple. In the words of the php.net Supported Versions page, "Each release branch of PHP is fully supported for two years from its initial stable release." After that, a branch gets two more years of security fixes only. Then it reaches end of life.

Counted from 2 October 2026, that rule leaves each supported branch with a very different runway.

Show data table
Months from 2 October 2026 to each branch's security end date, rounded down. Source: The PHP Group, Supported Versions, read 2 October 2026
Item Value
PHP 8.2 2
PHP 8.3 14
PHP 8.4 26
PHP 8.5 38

Moving from PHP 8.2 to 8.5 turns 2 months of remaining security support into 38 months.

Figure Months from 2 October 2026 to each branch's security end date, rounded down. Source: The PHP Group, Supported Versions, read 2 October 2026 The PHP Group, Supported Versions, read 2 October 2026

Take a team on PHP 8.2 today. Its branch has 2 whole months of security fixes left, because the end date is 31 December 2026. Moving to 8.5 turns 2 months of remaining security support into 38 months, so the upgrade buys three years without another forced move. In practice, that is the number a team lead takes to a planning meeting. The same arithmetic decides which PHP branch a Filament admin panel on Laravel should run on.

Moving to 8.4 instead gives 26 months. That is a fair choice when a key library does not yet support 8.5. Still, each step short of 8.5 brings the next forced upgrade a year closer.

Which PHP version do Laravel, Symfony, Drupal and WordPress require now?#

Laravel 13 requires PHP 8.3, current Symfony requires PHP 8.4, Drupal 11 requires PHP 8.3, and WordPress recommends PHP 8.3 or greater. So the framework a team runs usually sets its PHP floor before the PHP support calendar does. In fact, three of the four already sit at 8.3 or above.

Each figure comes from the project's own pages. For Laravel, the Laravel 13 release notes say: "Laravel 13.x requires a minimum PHP version of 8.3." For Symfony, the setup guide says "Install PHP 8.4 or higher". Also, the Symfony releases page lists Symfony 8.1, first out in May 2026, as needing PHP 8.4.0. Meanwhile, its long-term support branch, Symfony 7.4, still accepts PHP 8.2.

PHP branches each Laravel major accepts. Source: Laravel, Release Notes 13.x support policy, read 2 October 2026

Laravel releaseLowest PHPHighest PHP
Laravel 108.18.3
Laravel 118.28.4
Laravel 128.28.5
Laravel 138.38.5

For Drupal, the Drupal 11 core file sets MINIMUM_PHP to 8.3.0 and RECOMMENDED_PHP to 8.4. Its development branch for Drupal 12 already sets MINIMUM_PHP to 8.5.0. So the next Drupal major will not run on 8.4 at all.

WordPress is the gentle one. Its requirements page recommends "PHP version 8.3 or greater." But it also notes that WordPress still works on PHP 7.4, while warning that such old versions have reached their end of life. In short, a WordPress site can lag, but a Laravel or Symfony upgrade forces the PHP move with it.

What did PHP 8.4 add, and what does it deprecate?#

PHP 8.4, released on 21 November 2024, added property hooks, asymmetric visibility, lazy objects and array_find, and deprecated implicitly nullable parameter types. Property hooks and asymmetric visibility let a class drop most getter and setter boilerplate. Also, the one 8.4 deprecation most code bases meet is the implicit nullable parameter.

A property hook is a small get or set block written on the property itself. In the words of the PHP 8.4 migration guide, object properties "may now have additional logic associated with their get and set operations." When a property has only a get hook that reads other fields, it is "virtual". So it stores nothing and is worked out on every read.

Asymmetric visibility sets read and write access apart. With public private(set), any code can read the property, but only the class can change it. Before 8.4, that took a private property plus a getter method.

php
<?php
class Person
{
    public function __construct(
        public private(set) string $firstName,
        public private(set) string $lastName,
    ) {}

    // Virtual: worked out on every read, never stored.
    public string $fullName {
        get => $this->firstName . ' ' . $this->lastName;
    }
}

$p = new Person('Ada', 'Lovelace');
echo $p->fullName;      // Ada Lovelace
// $p->firstName = 'X'; // Error: the property is private(set)

Three smaller 8.4 additions are just as handy. First, lazy objects let a framework build an object that loads its data only when you first touch it. That works through the newLazyGhost() method of ReflectionClass. Second, the PHP 8.4 release page adds array_find(), array_find_key(), array_any() and array_all(). Each one replaces a common loop with a break. Third, the #[\Deprecated] attribute marks your own functions, methods and class constants as deprecated. So callers get the same warning PHP gives for its own old functions.

The deprecation to plan for is the implicit nullable type. The 8.4 deprecations page explains that "A parameter's type is implicitly widened to accept null" when its default is null. So function foo(T1 $a = null) now raises a warning, and the fix is ?T1 $a = null. Because older code used this form for years, it can produce a long list of warnings in an 8.4 upgrade. Also, the same page deprecates raising zero to a negative power and naming a class _.

What did PHP 8.5 add, and what does it deprecate?#

PHP 8.5, released on 20 November 2025, added the pipe operator, clone with, an always-on URI extension and #[\NoDiscard], and deprecated the backtick operator. In short, PHP 8.5 makes data pipelines and immutable objects cheaper to write. Its deprecations target old syntax such as backticks, non-canonical casts and case statements ending in a semicolon.

The pipe operator, |>, passes the value on its left into the function on its right. So instead of reading nested calls from the inside out, you read the steps from top to bottom. For example, the PHP 8.5 release page turns a title into a slug:

php
<?php
$title = ' PHP 8.5 Released ';
$slug = $title
    |> trim(...)
    |> (fn($str) => str_replace(' ', '-', $str))
    |> (fn($str) => str_replace('.', '', $str))
    |> strtolower(...);
// "php-85-released"

Clone with fixes a pain point of readonly classes. The PHP 8.5 migration guide says clone "is now a function and supports reassigning (readonly) properties during cloning." As a result, a withAlpha() method on a readonly class becomes one line: return clone($this, ['alpha' => $alpha]);.

The other headline additions are smaller but useful in daily work:

  • The URI extension. The migration guide says "An always enabled uri extension is added" for URIs and URLs under RFC 3986 and the WHATWG URL standard. So new Uri\Rfc3986\Uri($url) then getHost() replaces parse_url() and its loose parsing.
  • #[\NoDiscard]. PHP warns when a call's return value is thrown away, and a (void) cast marks a value you meant to ignore.
  • array_first() and array_last(). Both return the first or last value of an array, or null when it is empty.
  • Backtraces on fatal errors, such as a script that runs past its maximum execution time.
  • Closures and first-class callables in constant expressions, such as attribute arguments and default values.

Then come the deprecations. First, the 8.5 deprecations page deprecates the backtick operator as an alias for shell_exec(). Second, it deprecates the cast names (boolean), (integer), (double) and (binary) in favour of (bool), (int), (float) and (string). Also, ending a case with a semicolon is deprecated, and so is null as an array offset. In practice, most of these are one search and replace in an old code base.

What is coming in PHP 8.6, and when does it ship?#

PHP 8.6 reached its second release candidate on 24 September 2026, skipped RC1, and targets general availability on 19 November 2026. It adds partial function application, clamp() and readonly property defaults. Therefore a team should test against the release candidates now but ship on the GA release.

The PHP 8.6 timetable lists RC3 on 8 October, RC4 on 22 October and RC5 on 5 November 2026. Then GA follows on 19 November 2026. The plan is "Based upon a target GA in late November." Meanwhile, builds of PHP 8.6.0RC2 are on the PHP QA site today.

Three implemented RFCs (Requests for Comments, the documents PHP uses to propose and vote on changes) stand out:

  • Partial function application. A call with ? in place of an argument returns a closure that waits for the rest. So array_map(str_replace('hello', 'hi', ?), $arr) replaces a whole arrow function, and it fits the 8.5 pipe operator well.
  • clamp(). It returns a value held between a minimum and a maximum, so clamp($percentage, min: 0, max: 100) replaces a min() inside a max(). The RFC page reads "Implemented in PHP 8.6".
  • Readonly property defaults. A readonly property may now declare a default value. That pairs with the interface properties added in 8.4.

The RFC index lists more 8.6 work, such as #[\Override] for class constants and function arguments shown in error messages. It also lists 8.6 deprecations, such as returning a value from __construct(). So read the 8.6 migration guide once it appears at GA.

DiagramThe PHP 8.6 release path: RC1 skipped, RC2 on 24 September 2026, RC3 to RC5 through 5 November, GA on 19 November 2026. Source: PHP 8.6 release timetable, wiki.php.net, read 2 October 2026.

Which PHP version introduced readonly properties, enums, match and the other features teams search for?#

Match, named arguments, constructor promotion, union types, the nullsafe operator and the JIT arrived in PHP 8.0; enums, readonly properties and string-key unpacking in PHP 8.1. So every one of these PHP features for developers has been in PHP since 8.1 or earlier. And JSON_THROW_ON_ERROR goes back to 7.3, so on any supported branch they are already there.

Ten PHP features and the version that introduced each. Source: the PHP RFCs for each feature on wiki.php.net and the PHP manual, read 2 October 2026

FeatureIntroduced inWhat it does
JSON_THROW_ON_ERRORPHP 7.3json_decode() throws an exception instead of returning null
Union typesPHP 8.0a type such as int|string
Named argumentsPHP 8.0pass arguments by name, in any order
Constructor promotionPHP 8.0declare and assign properties in the constructor signature
Match expressionPHP 8.0a strict, value-returning switch
Nullsafe operatorPHP 8.0$a?->b() returns null instead of failing on null
JIT compilerPHP 8.0compiles hot code to machine code inside OPcache
EnumsPHP 8.1a closed set of named values as a type
Readonly propertiesPHP 8.1a property set once, then never changed
String-key array unpackingPHP 8.1[...$a, ...$b] with string keys

Source: the PHP RFCs for each feature on wiki.php.net and the PHP manual, read 2 October 2026.

Each row comes from the RFC or manual page that owns it. For match, the manual page says "Match expressions are available as of PHP 8.0.0." For readonly, the properties manual page dates it to PHP 8.1.0. It adds that "A readonly property can only be initialized once, and only from the scope where it has been declared." Finally, the JSON_THROW_ON_ERROR RFC is marked "Implemented (PHP 7.3)".

Try it
The PHP version your team runs today

Months of security support are counted from 2 October 2026.

2
31 December 2026

PHP 8.2: 2 months of security fixes left

Plan the upgrade now

PHP 8.5 is patched for 38 months, the longest window of any supported branch.

Features you already have (10)

  • JSON_THROW_ON_ERROR
  • Union types
  • Named arguments
  • Constructor promotion
  • Match expression
  • Nullsafe operator
  • JIT compiler
  • Enums
  • Readonly properties
  • String-key array unpacking

Features that need an upgrade (4)

  • Property hooks: PHP 8.4
  • Asymmetric visibility: PHP 8.4
  • Pipe operator: PHP 8.5
  • Clone with: PHP 8.5
Every feature in this guide and the PHP version that introduced it
JSON_THROW_ON_ERRORPHP 7.3
Union typesPHP 8.0
Named argumentsPHP 8.0
Constructor promotionPHP 8.0
Match expressionPHP 8.0
Nullsafe operatorPHP 8.0
JIT compilerPHP 8.0
EnumsPHP 8.1
Readonly propertiesPHP 8.1
String-key array unpackingPHP 8.1
Property hooksPHP 8.4
Asymmetric visibilityPHP 8.4
Pipe operatorPHP 8.5
Clone withPHP 8.5
Pick the PHP version your team runs today, 8.1 to 8.5, to see the features it already has, the ones that need an upgrade and the months of security support left from 2 October 2026. Source: the PHP RFCs and The PHP Group, Supported Versions, read 2 October 2026. Modelled, not measured.

Does turning on the JIT make PHP code faster?#

In the JIT's own RFC, bench.php fell from 0.32 to 0.14 seconds, so CPU-bound PHP code can run more than twice as fast. The JIT, or just-in-time compiler, turns hot PHP code into machine code while the program runs. So it pays on CPU-bound code such as numeric loops, by the RFC's own January 2019 measurement.

The JIT RFC by Dmitry Stogov and Zeev Suraski is dated 28 January 2019. It puts the result this way: "JIT makes bench.php more than two times faster". Also, on a Mandelbrot fractal test, the same RFC reports 0.011 seconds against 0.046 seconds on PHP 7.4. That is a gain of more than four times.

bench.php with and without the JIT0.32 against 0.14 seconds

0.32 s

Without JIT

0.14 s

With JIT

In the JIT RFC, bench.php ran more than twice as fast with the JIT on.

bench.php with and without the JIT (seconds per run, lower is faster)
Optionseconds per run, lower is faster
Without JIT0.32 s
With JIT0.14 s

Source: PHP RFC: JIT, Dmitry Stogov and Zeev Suraski, 2019

Mandelbrot with and without the JIT0.046 against 0.011 seconds

0.046 s

PHP 7.4, no JIT

0.011 s

With JIT

On the RFC's Mandelbrot test, the JIT gave a gain of more than four times.

Mandelbrot with and without the JIT (seconds per run, lower is faster)
Optionseconds per run, lower is faster
PHP 7.4, no JIT0.046 s
With JIT0.011 s

Source: PHP RFC: JIT, Dmitry Stogov and Zeev Suraski, 2019

Two limits matter. First, these are 2019 figures, taken while PHP 8.0 was being built. So they show the shape of the gain, not what your server does on 8.5. Second, the JIT is off unless you turn it on. It runs inside OPcache, the PHP extension that keeps compiled scripts in memory. The OPcache configuration page lists the default for opcache.jit as "disable". It notes that before PHP 8.4.0 the default was "tracing". Since opcache.jit_buffer_size defaults to 64M, setting opcache.jit=tracing on a server with OPcache enabled is enough to try it.

Which official pages should a PHP upgrade be built from?#

Build an upgrade from six official pages: the php.net support table, your framework's requirements, then the PHP 8.4 and 8.5 migration guides for deprecations and new features. Because the php.net migration guides list every deprecation and new feature per release, an upgrade plan is built from them. Release recaps come second.

  1. php.net Supported Versions: pick the target branch and note its security end date.
  2. Laravel 13 release notes or Symfony releases: confirm the PHP floor of the framework version you will run.
  3. PHP 8.4 deprecated features: find the implicit nullable types and the other warnings 8.4 raises.
  4. PHP 8.4 new features: take the exact syntax for hooks and asymmetric visibility.
  5. PHP 8.5 deprecated features: find the backticks, old cast names and case semicolons.
  6. PHP 8.5 new features: take the syntax for the pipe operator, clone and the URI classes.

Read the deprecation pages before the feature pages. That way a clean log on the new branch comes first. Then new syntax can follow one class at a time.

  1. Pick the target branch and confirm the framework floor.

    php.net Supported Versions, then the Laravel 13 release notes or Symfony releases.

  2. Read the deprecation pages first.

    PHP 8.4 and PHP 8.5 deprecated features, so a clean log on the new branch comes first.

  3. Then adopt new syntax one class at a time.

    PHP 8.4 and PHP 8.5 new features: hooks, asymmetric visibility, the pipe operator, clone and the URI classes.

What does a small PHP 8.5 class using these features look like?#

One short PHP 8.5 file can use a property hook, asymmetric visibility, the pipe operator, clone with and array_first together. So five of the new features fit in one value object and one pipeline of under forty lines.

php
<?php
// Runs on PHP 8.5 or later: php release.php
final class Release
{
    public function __construct(
        public private(set) string $branch,      // 8.4: read anywhere, write inside the class
        public readonly string $status = 'stable',
    ) {}

    // 8.4: a virtual property hook, worked out on every read
    public string $label {
        get => 'PHP ' . $this->branch . ' (' . $this->status . ')';
    }

    public function withStatus(string $status): static
    {
        // 8.5: clone with, reassigning a readonly property on the copy
        return clone($this, ['status' => $status]);
    }
}

$next = ['8.6', '8.5', '8.4']
    |> (fn(array $b) => array_map(fn(string $v) => new Release($v, 'RC2'), $b)) // 8.5: pipe
    |> array_first(...);                                                        // 8.5: array_first

echo $next->label, PHP_EOL;                    // PHP 8.6 (RC2)
echo $next->withStatus('GA')->label, PHP_EOL;  // PHP 8.6 (GA)

Run it with php release.php on PHP 8.5. Each step maps to one page above. The hook and the private(set) come from the 8.4 guide. Then the clone call, the pipe and array_first() come from the 8.5 guide and release page.

When is turning on the JIT or moving to PHP 8.6 early the wrong tool?#

In the same RFC, WordPress moved only from 315 to 326 requests per second with the JIT on, so a database-bound application gains more from query and cache work. For request-bound web applications, the JIT is the wrong tool and a release candidate is the wrong production target. Instead, profile queries first and wait for 8.6 GA.

The JIT RFC said so itself. It "doesn't seem to significantly improve real-life apps like WordPress (with opcache.jit=1235 326 req/sec vs 315 req/sec)." So the gain was 11 requests per second, measured in January 2019.

WordPress throughput with and without the JIT315 against 326

315

Without JIT

326

With the JIT on

In the same RFC, WordPress moved only from 315 to 326 requests per second with the JIT on.

WordPress throughput with and without the JIT (requests per second, higher is faster)
Optionrequests per second, higher is faster
Without JIT315
With the JIT on326

Source: PHP RFC: JIT, Dmitry Stogov and Zeev Suraski, 2019

Three cases call for a different tool:

  • A slow web page. Most of its time goes to the database and the network, not to PHP running loops. Profile the queries, add indexes and cache results first; the Laravel performance guide walks through that work.
  • A production move to 8.6 before 19 November 2026. A release candidate can still change, and the timetable keeps three more on the plan. Run your test suite on RC2 or RC3 now, and deploy 8.6 after GA.
  • A large old code base on 8.1 or 8.2. Jumping straight to the newest syntax by hand is slow and error prone. Instead, let an automated tool rewrite the mechanical parts first, then adopt hooks and pipes where they help.

Where should a PHP upgrade go next?#

For the upgrade itself, Rector automates most mechanical code changes, and the Laravel performance guide covers what the JIT will not. So the next step is the upgrade, and the posts and pages below cover it.

First, the Rector migration guide shows how to script the move between PHP versions. Then the Laravel performance guide covers queries, caching and queues. For a wider view, PHP compared with JavaScript sets out where each language fits. Also, the Tenancy for Laravel review looks at one multi-tenant package on modern Laravel.

If you want people to do the work, Atyantik has a PHP development team and a maintenance and support practice for version upgrades. Still, the six php.net and framework pages above are enough to plan and run the upgrade on your own.

Questions this post answers

Which PHP features for developers matter in October 2026?
In October 2026 PHP 8.5 is the current stable release, PHP 8.6 is due on 19 November 2026, and the features worth adopting first arrived in 8.4 and 8.5.
How long does each supported PHP version keep getting security fixes?
PHP 8.2 stops receiving security fixes on 31 December 2026, while PHP 8.5 is covered until 31 December 2029.
Which PHP version introduced readonly properties, enums and match?
Match, named arguments, constructor promotion, union types, the nullsafe operator and the JIT arrived in PHP 8.0; enums, readonly properties and string-key unpacking in PHP 8.1.

Keep reading