PHP 8.6.0 RC4 Ships, Hours After Team Emergency-Patches a Critical RCE Flaw
The fourth and probably final release candidate for PHP 8.6 landed Wednesday, arriving on the same morning the team had to panic-patch a critical remote-code-execution flaw. Release manager Matteo Beccati tagged the branch, and the commit message is about as terse as you'd get mid-release: "Tag for php-8.6.0RC4." That's all. There's a lot packed behind those four words of brevity, though.
First the basics. RC4 is a test-only build. From this point the 8.6 branch takes bug fixes only, the feature list is locked, and the whole thing points at the 19 November 2026 general availability date. This candidate trims about 50 issues that surfaced since RC3. If you meant to test 8.6 before it goes live, this is your last real chance to do so.
The 8.6 cycle ran almost on schedule: Alpha 1 in early July, a soft feature freeze around Beta 1 on 13 August, and a hard freeze two weeks later. RC2 dropped 24 September as the first real candidate. RC3 came 8 October. Then this. PHP 8.6 has no RC1, for the record. A packaging script bumped API version numbers at the wrong moment, so the release managers nuked that tag and shipped RC2 instead. The official announcement didn't mince words: "It is not a typo: a mistake was made while packaging RC1, so RC2 was released instead." Three people are steering this cycle: Daniel Scherzer, Matteo Beccati, and Joe Ferguson. A tight crew for one of the web's most loaded languages.
The headline features
Partial function application is the one people have been waiting on. Call a function with a ? to stand in for one argument, or ... for the rest, and you get back a Closure ready to take what's missing later on.
function add(int $a, int $b, int $c = 0): int
{
return $a + $b + $c;
}
$addOne = add(1, ?);
var_dump($addOne(5)); // int(6)
The engine compiles a few patterns like array_map(pfa, ...) into a plain foreach when it can, and it composes cleanly with 8.5's pipe operator. It's a small addition, honestly, but it's the kind of thing modern languages have offered for years and PHP developers keep asking for.
clamp() finally kills the max($min, min($value, $max)) idiom you've probably written a hundred times.
var_dump(clamp(140, min: 0, max: 100)); // int(100)
A Time\Duration class shows up in ext/date, and readonly properties can now carry a default value instead of forcing every assignment into the constructor. That last change matters more than it sounds. It quietly removes a whole class of "well, I'll just pass it in" boilerplate from your code. Minor. The kind of thing you don't miss until it's gone.
Extensions get their share too. There's a native polling API meant to finally replace stream_select(), structured error handling for streams, TLS 1.3 early data under OpenSSL, and a new mysqli_quote_string() that actually escapes and quotes in one go. All of it ships in RC4 the same as it will in the final release, since the features are frozen.
The security backdrop
Here's where the day gets uncomfortable. Hours before RC4 shipped, the team issued emergency fixes for two critical RCE flaws. The community has dubbed them "php2shell," and they reach every PHP version from 5.4 through 8.5.11. That's a genuinely long tail.
Both rate at CVSS 9.2. The fixes land in 8.5.12, 8.4.27, 8.3.36, and 8.2.35. The work came out of Wiz Research with a noted contribution from Google's Gemini, and the mechanics are nasty enough to make any security team sit up.
PHP has long used longjmp() (technically zend_bailout()) to escape out-of-memory and other fatal conditions. When that abort fires mid-request, the data structures in flight get left half-built. The cleanup phase then reaches for memory that's already freed. Multiple labs confirmed the whole thing: Datadog, Cloudflare, Fastly, Google Cloud, and ox.security all weighed in, and they agree the attack needs no login, no special endpoint, and no help from your application code.
It fires before any of your code runs. Trigger it with a large HTTP POST, typically via the always-on session.upload_progress path, and an attacker can even nudge past ASLR with a calibrated memory layout. The quietly nasty part: a successful hit doesn't crash the worker. It just serves commands and leaves behind a plain OOM error. Nobody glancing at the logs will think to look.
The fix isn't small. A single upstream commit, roughly 10,700 lines across about 300 files, rewrote OOM handling to be recoverable instead of abortive. It also hardened the multipart upload parser and stopped the upload-progress handler from invoking class code while it decoded a session.
The vendor consensus is blunt. Only patching fully resolves this. Turning off session.upload_progress trims some confirmed paths but leaves others open, and PHP 8.1 and earlier stay on the wrong side of the line, they've already hit end of life. Upgrading to a supported version is the only real fix. Keep in mind that "mitigation" guides floating around are not the answer here.
Three things, roughly in urgency order. Patch first: if you're on 8.5, move to 8.5.12 or later. If you're lagging, grab 8.4.27, 8.3.36, or 8.2.35. Test 8.6 in CI before trusting it. The freeze is over, but RC builds can still shift on fixes, and you'll want to verify against the stricter session defaults (session.use_strict_mode, session.cookie_httponly, and session.cookie_samesite all flip to safer values by default) plus the fresh deprecations, some of which now throw instead of just warn. Start your upgrade plan now. GA sits at 19 November 2026, active support runs to the end of 2028, and EOL lands two years after that. If you're still on 8.2, heads up: it dies 31 December 2026. You've got about two months left.
PHP 8.6.0 RC4 is the "almost there" signal the community's been waiting on. Whether it becomes the 8.6 everyone actually runs next month depends on a clean final QA pass, sure, and on how fast the industry gets in gear against php2shell. Head here to the php-src tree and the RC4 NEWS file for the details, and check the PHP security page to confirm which build you're actually running.
Release php-8.6.0RC4 · php/php-src
Tag for php-8.6.0RC4
