Software 45159 Published by

The PHP Group shipped three release candidates at once, with 8.6.0 RC5 being the final one before 8.6.0 goes general availability on 19 November 2026. The two older lines got their next maintenance candidates too, 8.5.13 RC1 and 8.4.28 RC1, each inheriting fixes for the two critical RCE vulnerabilities disclosed on 21 October. 8.6's headline feature is partial function application, letting you pre-fill arguments with ? or ... placeholders, while the RC-level changelogs are dominated by the usual memory-safety and JIT fixes. All three are test software, not for production, and should release as stable versions within days if no blockers turn up.



PHP ships final 8.6.0 RC alongside 8.5 and 8.4 release candidates

PHP 8.6.0 lands on 19 November. Three release candidates shipped this week, and they all carry fixes for two critical RCE vulnerabilities.

The PHP Group shipped all three at once, spanning essentially its entire supported surface. 8.6.0 RC5 is the final candidate before general availability. 8.5.13 RC1 and 8.4.28 RC1 are the next maintenance releases for the two older supported lines. Tags landed between 3 and 4 November UTC, a day or two early against the scheduled 5 November target.

They are not for production. That's the whole point. An RC is a potential final release: feature-complete, believed stable, but not yet declared production-ready. If no blocking bugs surface across the RCs, the next build becomes official. So treat all three as test software.

Screenshot_from_2026_06_30_15_03_26

A security backdrop

These releases did not arrive in a vacuum. On 21 October the PHP security team patched two critical vulnerabilities rated CVSS 9.2, both allowing unauthenticated remote code execution. CVE-2026-109618 and CVE-2026-109619 are already baked into all three new candidates.

CVE-2026-109618 is RCE via out-of-memory corruption. An OOM event can interrupt PHP mid-request, when internal request data is only partially initialized, and cleanup then treats that invalid partial data as if it were valid. CVE-2026-109619 is RCE via stale global state, where request-owned state survives after its memory is freed, letting a later request use stale data before a fresh initialization resets it.

The team rated the risk highest for mod_php, because a demonstrated exploit triggers the attack before any application code runs. The only complete mitigation was to update, though partial path-specific fixes were published. PHP went so far as to ship minimal source backports for 7.4, 8.0 and 8.1, branches that normally get nothing. That says a lot about how severe the bugs were.

A second advisory, CVE-2026-115560, remains unpublished in full at RC time. It concerns session upload progress, and the new builds carry a session-ID hardening under Session: validate the whole session ID instead of stopping at the first NUL byte. That lines up with the pending advisory, even though the fully worded advisory hadn't dropped yet.

8.6 is nearly done

At RC5 the branch is feature-complete. Every change since RC1 has been bug fixing, build fixing, or stabilization. The headline is partial function application, the feature people have been waiting years for. Call a function with placeholders and get back a closure for the rest. The ? marks a single argument for later. The ... soaks up all remaining ones. Named arguments work with placeholders too, and they can reorder parameters. It passed its RFC nearly unanimously, 33 to 0.

The rest is less flashy but real. clamp() clamps a value to a range and throws if the range is inverted. Time\Duration gives you an immutable duration class. Readonly property defaults are finally allowed, and error messages can now display the arguments that were passed.

Read the RC5 changelog and you'll see the actual texture of recent PHP work: a long list of memory-safety fixes. Use-after-frees, out-of-bounds reads, double-frees across DOM, phar, zip, curl, FPM, OpenSSL. JIT and OPcache dominate the fix counts, and memory safety is the standing strategy.

There's a detail that only shows up if you follow this closely. PHP 8.6 has no RC1. It jumped straight to RC2 on 24 September. Release manager Daniel Scherzer explained why: when a new RC branch is created, release managers also bump the API version numbers for the next minor line, and an automation script used by this year's rookies bumped them at the wrong time. The code tagged as RC1 ended up with the wrong API numbers, so it had to be retagged. Hence RC2 is the first one.

The announcement was blunt about it: "It is not a typo: a mistake was made while packaging RC1, so RC2 was released instead." It's a packaging slip caught by supervision, not a correctness failure. The community's fondness for zero-indexing didn't help either.

What to do

If you're planning an 8.6 upgrade, test the RCs now. They're the closest thing to final. Watch your logs for the new deprecations, since they'll start lighting up: return inside a finally block, values returned from constructors, the third argument to define(), and words like let or is now clashing with class names.

You're already covered on the RCEs if you're on 8.5.12 or 8.4.27 or newer. Anything at 8.1 and below gets no upstream fixes, so an LTS vendor or an upgrade is your call.

Release php-8.6.0RC5 · php/php-src

Tag for php-8.6.0RC5

Release php-8.6.0RC5 · php/php-src

Release php-8.5.13RC1 · php/php-src

Tag for php-8.5.13RC1

Release php-8.5.13RC1 · php/php-src

Release php-8.4.28RC1 · php/php-src

Tag for php-8.4.28RC1

Release php-8.4.28RC1 · php/php-src