---
title: PHP 8.6 Preview: New Features Tested on RC3, and the PHP 8.5 Syntax WordPress and Magento Code Can Use Now
url: https://ilogr.com/php-8-6-preview/
published: 2026-10-14
updated: 2026-10-22
author: iLogr
categories: Development, Magento, WooCommerce, WordPress
reading_time: 11 min
description: PHP 8.6 is due 19 Nov 2026 and RC3 is for testing only. It adds partial application and clamp(). In production, run the PHP your whole stack supports.
---

# PHP 8.6 Preview: New Features Tested on RC3, and the PHP 8.5 Syntax WordPress and Magento Code Can Use Now

**In short:** PHP 8.6 is scheduled for 19 November 2026, and its release candidates are for testing only. Use a PHP version your complete stack supports: WordPress core supports 8.5 from 6.9, Magento 2.4.9 supports only 8.5, and WooCommerce lists 8.3 or later and documents testing through 8.4.

Everything below was checked against the third release candidate, 8.6.0RC3, and every snippet was run on it. Nothing here describes a released version: features can still change before general availability.

The few code snippets in this article are short examples for learning, provided as is and without warranty of any kind, and you use them entirely at your own risk. PHP 8.6 is a test release: try every snippet and check on your own machine or a staging copy first, never on a live site, store or database, and take a full backup before you change the PHP version of any server. iLogr accepts no responsibility for any loss, damage or other problem arising from their use.

## When is PHP 8.6 released?

General availability is scheduled for 19 November 2026 [1]. The soft feature freeze was on 13 August and the hard freeze on 22 September. RC2 shipped on 24 September and RC3 on 8 October; RC4 is planned for 22 October and RC5 for 5 November [1][2]. There was no released RC1: the code tagged for it carried the wrong API numbers, so the first candidate was published as RC2 [3]. Each announcement says the same thing: "Please DO NOT use this version in production, it is an early test version." [2]

PHP 8.5 is a stable production release, but use it only where your platform, plugins and dependencies support it. It has active support until 31 December 2027 and security support until 31 December 2029, while PHP 8.2 leaves security support on 31 December 2026 [4]. The [guide to the PHP 8.2 end of life](https://ilogr.com/php-8-2-end-of-life-upgrade-rector-phpstan/) covers that migration.

## What are the new features in PHP 8.6?

The `UPGRADING` file at the `php-8.6.0RC3` tag is the most reliable list, because it describes what was actually merged [5]. These are the changes most WordPress, WooCommerce and Magento developers will notice.

**Partial function application.** A call with `?` or `...` in place of arguments no longer runs the function; it returns a closure that waits for the missing arguments, keeping the original's types [6]. It finishes what PHP 8.5's pipe operator started: a pipe step that needs more than one argument no longer has to be wrapped in a closure.

```php
$slug = '  Hello World From PHP  '
    |> trim(...)
    |> strtolower(...)
    |> str_replace(' ', '-', ?);

var_dump($slug); // string(20) "hello-world-from-php"
```

On PHP 8.5.11 the same code stops with a parse error at the `?`. Every parameter created by a `?` placeholder is required, even where the original parameter was optional [7].

**clamp().** `clamp($value, $min, $max)` returns the value when it is in range and otherwise the nearest bound, and throws a `ValueError` when the minimum is larger than the maximum [5][8]:

```php
var_dump(clamp(15, 0, 10)); // int(10)
var_dump(clamp(-3, 0, 10)); // int(0)
clamp(5, 10, 0);            // throws ValueError: $min is larger than $max
```

**Readonly properties with default values.** `public readonly int $timeout = 30;` is now valid; on PHP 8.5 it is a fatal error [5].

**Smaller additions.** `#[\Override]` on class constants and enum cases, a `Time\Duration` class, a `SortDirection` enum, error positions in `json_last_error_msg()`, and `isReadable()` and `isWritable()` on reflected properties [5].

**Changed defaults that are easy to miss:**

- **Session defaults are stricter.** `session.use_strict_mode` and `session.cookie_httponly` now default to 1, and `session.cookie_samesite` to "Lax" [5][9]. Check any code that starts a PHP session and relies on the old defaults, such as a payment return that posts back from another domain. Magento sets the HttpOnly and SameSite options from its own configuration; WordPress core and WooCommerce do not call `session_start()`.
- **`trim()` now strips form feeds,** as do `rtrim()` and `ltrim()` [5]. In the test, a string wrapped in form feeds trimmed to 5 characters on 8.6.0RC3 and 7 on PHP 8.5.11.

## What does PHP 8.6 deprecate?

Each deprecation was voted on separately. Four failed, among them `list()`, and every one that passed is in `UPGRADING` at RC3 [5][10]. They fall into two groups.

**Runtime deprecations** fire only when the line runs:

- `is_integer()`, `is_long()`, `is_double()` and `doubleval()` (use `is_int()`, `is_float()` and `floatval()`)
- `spl_object_hash()` (use `spl_object_id()`)
- `metaphone()`, `strcoll()`, `spl_classes()`, `mysqli_get_charset()`, a third argument to `define()`, and objects passed to `array_walk()` or `http_build_query()`

**Compile-time deprecations** fire as soon as the file is loaded, whether or not the code runs:

- returning a value from `__construct()` or `__destruct()`
- `return` inside a `finally` block
- `let` or `is` as the name of a class, function or constant
- a function named `readonly`, or a class constant named `namespace`
- `?array` as the return type of `__debugInfo()`

A deprecation is a notice, and a correctly configured production server logs it rather than showing it. Two things make 8.6 less forgiving. First, `clamp()` is now built in, so a plugin or module that declares its own global `clamp()` without a `function_exists()` check stops with "Cannot redeclare function clamp()". WordPress 7.1 ships a correctly guarded `clamp()` polyfill, as WordPress 6.9 did for `array_first()` and `array_last()` [11]. Second, some platforms turn deprecations into exceptions, as the field note below shows.

The `is` deprecation has already caught a widely used library: `guzzlehttp/promises` has a public class called `Is` [12]. A request to move the deprecation to PHP 8.7 was closed on 2 October 2026, with the reply that a revert would need an RFC [13]. The Guzzle maintainer announced on 18 October 2026 that versions 2.6.0 and 3.1.0 add a replacement class, `State`, and that `Is` will be removed in 4.0.0 [12]. Those releases keep `Is` as a deprecated class, so in a test on 8.6.0RC3 loading it still raised the notice. Guzzle ships inside WordPress plugins and is a Magento dependency, so this one deprecation reaches a long way.

## What happens when WordPress, WooCommerce and Magento code runs on PHP 8.6.0RC3?

**Field note: a test on release candidate 3.** I used the official Docker images `php:8.6.0RC3-cli` and `php:8.5-cli` (PHP 8.5.11) with default settings. Every PHP file of four codebases was compiled with `php -l` under both versions, keeping only the messages that appeared on 8.6; that finds compile-time deprecations without running anything. The same code was searched for calls to the runtime-deprecated functions.

| Codebase | PHP files | New compile-time deprecations on 8.6.0RC3 | Calls to runtime-deprecated functions |
| --- | --- | --- | --- |
| WordPress 7.1.3 core | 1,315 | 1, in a file WordPress never loads on PHP 8.1 or later | 1, in the bundled getID3 library |
| 12 widely used WordPress plugins | 7,567 | 8, in 6 of the 12 plugins | 4, in 2 plugins |
| WooCommerce 11.2.1 | 3,664 | 1, a constructor that returns a value | 3 |
| Magento Open Source 2.4.9, application, libraries and vendor packages, with paths matching `/Test/`, `/tests/` and `/dev/` excluded | 33,378 | 21, 7 of them in Magento's own code | 28 lines in Magento's own code |

The lint comparison found one new compile-time deprecation in WordPress core, in `wp-includes/php-compat/readonly.php`, which WordPress loads only below PHP 8.1. This does not establish runtime compatibility with PHP 8.6. Six of the twelve plugins raised something, including a return inside a `finally` block and an SEO plugin's bundled copy of Guzzle's `Is` class.

Magento was the real finding. Its bootstrap sets `error_reporting(E_ALL)` and registers an error handler that throws an exception for every reported error, deprecations included. With that handler in place, I loaded five classes the lint had flagged, among them Magento's `ModuleList`, plus one control class. On PHP 8.5.11 all six loaded. On 8.6.0RC3 the five flagged classes threw "Deprecated Functionality" exceptions and the control loaded normally. `bin/magento --version` printed "Magento CLI 2.4.9" on PHP 8.5.11; on 8.6.0RC3 it exited with status 1, stopped by a `spl_object_hash()` deprecation in `laminas-servicemanager`, one of Magento's dependencies.

That is not a fault in Magento: Adobe supports 2.4.9 on PHP 8.5 only and has said nothing yet about 8.6 [14]. It shows how far the deprecations reach, and why no Magento store should run an 8.6 build before Adobe supports it.

**Field note.** The same pattern showed up with PHP 8.5. On a WordPress site, a plugin that was not ready for 8.5 kept the site on PHP 8.4 until its vendor shipped an update. The platform was ready first; a single plugin set the pace. Expect the same with 8.6.

![Why one deprecation stopped bin/magento on PHP 8.6.0RC3. Step 1: a Magento dependency, laminas-servicemanager, calls spl_object_hash(). Step 2: PHP 8.6.0RC3 raises a deprecation notice for that call; PHP 8.5.11 raises nothing. Then two paths. On the left, most PHP code under production settings: the notice is logged and the code keeps running. On the right, Magento's error handler: the bootstrap reports every error and the handler throws an exception for each one, deprecations included, so the command exits with status 1 before printing its version. A band at the foot says that on PHP 8.5.11 the same command printed Magento CLI 2.4.9, and that Adobe supports Magento 2.4.9 on PHP 8.5 only.](https://ilogr.com/wp-content/uploads/2026/10/php-8-6-deprecation-stops-magento-cli.webp)

*On PHP 8.6.0RC3, Magento’s own error handler turned a dependency’s deprecation notice into an exception.*

## Which PHP 8.5 features can WordPress and Magento code use now?

PHP 8.5 brought the pipe operator, `clone()` with new property values, the `#[\NoDiscard]` attribute, a built-in URI extension, and `array_first()` and `array_last()` [15]. Whether your code may use them depends on the oldest PHP version it must run on, not on your own server:

- **WordPress** supports PHP 8.5 from WordPress 6.9 [16], recommends 8.3 or later and still runs on 7.4 [17]. A plugin published on WordPress.org must work on every PHP version it declares.
- **WooCommerce** states PHP 8.3 or later, "tested up to PHP 8.4" [18]; 8.5 is not on its requirements page yet. WooCommerce 11.6, planned for February 2027, will require PHP 8.1 [19].
- **Magento 2.4.9** supports PHP 8.5 only; 8.4 is allowed for upgrades and not recommended for production [14][20]. A module written only for 2.4.9 can use 8.5 syntax; one that must also install on 2.4.8 cannot.

So 8.5 syntax is safe in custom code that runs only on your own PHP 8.5 servers: a site-specific plugin or theme, or a Magento 2.4.9 module. In anything distributed to others, keep syntax compatible with the lowest PHP version you declare. WordPress polyfills provide selected functions, including `array_first()`, `array_last()` and `clamp()`; they cannot provide newer language syntax [11][15].

The first snippet in this article runs on PHP 8.5 today if its last step is written as an arrow function, `(fn (string $s): string => str_replace(' ', '-', $s))`, instead of the `?` placeholder. `clone()` with new values makes immutable value objects much shorter, because readonly properties can be changed while copying:

```php
final readonly class Money
{
    public function __construct(public int $amount, public string $currency) {}

    public function withAmount(int $amount): static
    {
        return clone($this, ['amount' => $amount]);
    }
}

$sale = new Money(1999, 'GBP')->withAmount(1499);
var_dump($sale->amount, $sale->currency); // int(1499) string(3) "GBP"
```

Both gave the same output on PHP 8.5.11 and 8.6.0RC3. `#[\NoDiscard]` suits functions whose result must not be ignored, such as one that reports whether stock was reserved; ignoring it raises a warning unless the call is cast to `(void)` [15]. The URI extension follows two standards that disagree: given the same address, the RFC 3986 parser in the test kept an explicit `:443` port and the browser-style WHATWG parser dropped it. Pick one standard per job.

## How do you check a PHP 8.6 fix?

Treat every fix as a claim until a test on both PHP versions agrees. Three cautions come out of the test:

- **Check 8.6 claims against the release itself.** Older answers, tutorials and tools predate PHP 8.6. They may read `str_replace(' ', '-', ?)` as a syntax error, or suggest adding a global `clamp()` helper, which is exactly the declaration that fails on 8.6. Use the `UPGRADING` file for the exact release candidate, and treat any 8.6 claim you cannot point to there as unverified.
- **The tempting fix is to hide the notice.** Lowering `error_reporting` or adding `@` hides a deprecation without fixing it, and in Magento it bypasses a handler that exists on purpose. For a third-party library such as Guzzle, use a release that carries the maintainer's fix and follow its migration notes; never edit files under `vendor/`.
- **Let the evidence decide.** The lint comparison above is the method: compile on both versions, keep only the new messages, make one fix per file, and let the test suite on both versions decide. The [PHP 8.2 end-of-life guide](https://ilogr.com/php-8-2-end-of-life-upgrade-rector-phpstan/) describes the same pattern with Rector and PHPStan.

## What should you do before 19 November 2026?

1. **Keep production on a PHP version supported by your complete stack.** None of WordPress, WooCommerce or Adobe lists PHP 8.6 as supported yet. Ask your host which PHP versions it offers and when it plans to add 8.6, because a host that is behind also limits what your code may use.
2. **Test on a staging copy or in CI,** never on a live site: compile every file with `php -l` on an 8.6 release candidate and compare with your current version.
3. **Search your own code** for the runtime-deprecated functions above, and for any global `clamp()` without a `function_exists()` check.
4. **List the dependencies that need an update or a migration,** starting with `guzzlehttp/promises`, where 2.6.0 and 3.1.0 add the replacement `State`, so find the callers that still load `Is`, bundled copies included, and any package with a class named `Is` or `Let`.
5. **Check session behaviour** wherever your code starts a PHP session, especially cross-domain payment returns.
6. **Recheck at general availability.** The final build and the platforms' own support statements decide what is safe in production.

For Magento, the [Magento 2.4.9 upgrade guide](https://ilogr.com/magento-2-4-9-upgrade-extensions/) on extension compatibility and PHP 8.5 comes first; PHP 8.6 is a question for after Adobe adds it to the system requirements.

**Next step:** On a staging copy or in CI, compile your own code with `php -l` on an 8.6 release candidate and on your current PHP version, then compare the messages.

## References

1. [PHP 8.6 release timetable (PHP wiki, todo/php86)](https://wiki.php.net/todo/php86). Used for: the release dates for RC3 to RC5 and general availability.
2. [PHP 8.6.0 RC3 available for testing (php.net news, 8 October 2026)](https://www.php.net/archive/2026.php#2026-10-08-1). Used for: RC3’s date and the testing-only warning.
3. [No PHP 8.6 RC 1 (Daniel Scherzer, release manager)](https://scherzer.dev/Blog/20260923-no-php86-rc-1). Used for: why there was no RC1.
4. [Supported Versions (php.net)](https://www.php.net/supported-versions.php). Used for: support end dates for PHP 8.5 and 8.2.
5. [UPGRADING at tag php-8.6.0RC3 (php-src on GitHub)](https://github.com/php/php-src/blob/php-8.6.0RC3/UPGRADING). Used for: the list of changes and deprecations at RC3.
6. [RFC: Partial Function Application v2 (PHP wiki)](https://wiki.php.net/rfc/partial_function_application_v2). Used for: how partial function application works.
7. [RFC: Partial Function Application, Handling of Optional Parameters (PHP wiki)](https://wiki.php.net/rfc/partial_function_application_optional_placeholder). Used for: that placeholder parameters are always required.
8. [RFC: clamp v2 (PHP wiki)](https://wiki.php.net/rfc/clamp_v2). Used for: the clamp() behaviour and its error.
9. [RFC: Session security defaults (PHP wiki)](https://wiki.php.net/rfc/session_security_defaults). Used for: the stricter session defaults.
10. [RFC: Deprecations for PHP 8.6 (PHP wiki)](https://wiki.php.net/rfc/deprecations_php_8_6). Used for: which deprecations were accepted and which failed.
11. [wp-includes/compat.php at WordPress 7.1.3 (wordpress-develop on GitHub)](https://github.com/WordPress/wordpress-develop/blob/7.1.3/src/wp-includes/compat.php). Used for: the clamp() polyfill and PHP 8.5 helper functions in WordPress.
12. [Using "is" as a class name is deprecated since 8.6 (guzzle/promises issue 244)](https://github.com/guzzle/promises/issues/244). Used for: the Guzzle Is class problem, its replacement State and the 18 October announcement.
13. [Consider deferring the "is"/"let" identifier deprecation to PHP 8.7 (php-src issue 23990)](https://github.com/php/php-src/issues/23990). Used for: the closed request to defer the deprecation.
14. [Adobe Commerce system requirements (Adobe Experience League)](https://experienceleague.adobe.com/en/docs/commerce-operations/installation-guide/system-requirements). Used for: Magento 2.4.9 PHP support.
15. [PHP 8.5 release announcement (php.net)](https://www.php.net/releases/8.5/en.php). Used for: the PHP 8.5 features.
16. [PHP Compatibility and WordPress Versions (WordPress Core Handbook)](https://make.wordpress.org/core/handbook/references/php-compatibility-and-wordpress-versions/). Used for: WordPress support for PHP 8.5.
17. [Requirements (WordPress.org)](https://wordpress.org/about/requirements/). Used for: WordPress PHP recommendations and minimum.
18. [Server requirements (WooCommerce documentation)](https://woocommerce.com/document/server-requirements/). Used for: WooCommerce PHP requirements and tested version.
19. [New Requirement for WooCommerce 11.6: PHP 8.1+ (WooCommerce Developer Blog, 29 September 2026)](https://developer.woocommerce.com/2026/09/29/php-8-1-requirement/). Used for: the WooCommerce 11.6 PHP 8.1 requirement.
20. [Adobe Commerce 2.4.9 release notes (Adobe Experience League)](https://experienceleague.adobe.com/en/docs/commerce-operations/release/notes/adobe-commerce/2-4-9). Used for: the PHP versions for Magento 2.4.9.

Image credit: the PHP logo is by Colin Viebrock, used unaltered under [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/).
