PHP 8.6 release date, upcoming features, and RFC status

php
release
Nabil Hassen
Nabil Hassen
Dec 16, 2025
PHP 8.6 release date, upcoming features, and RFC status
Last updated on Dec 16, 2025
Table of contents:

PHP 8.6: expected release window and the RFCs being proposed right now

You’ll get a current, practical view of what PHP 8.6 is likely to include. We’ll pin down the most likely release window based on the last few major releases. Then we’ll walk through the RFCs that are explicitly targeting PHP 8.6 or are being built for the next PHP 8.x. Everything here is focused on day to day PHP code you’ll actually write in CLI scripts and web apps.

Expected PHP 8.6 release window

PHP has been shipping major versions around late November for years. PHP 8.5 shipped on November 20, 2025, and PHP 8.4.0 shipped in late November 2024. If the project keeps the same cadence, PHP 8.6 is most likely to ship in the third week of November 2026. A reasonable expectation is a Thursday release (like recent majors), so think around November 19, 2026 or November 26, 2026, with the exact date depending on how many RCs are needed.

Approved or already being implemented for the next release

Partial Function Application (v2)

Status: Accepted

This adds a placeholder based syntax to partially apply arguments to any callable. If you call a function and leave one or more arguments as placeholders, PHP returns a Closure that remembers what you already provided. You can then call that closure later with the missing values.

<?php
 
function add(int $a, int $b, int $c): int
{
return $a + $b + $c;
}
 
$add10AndX = add(10, ?, 5); // returns Closure: fn(int $b): int
 
echo $add10AndX(3); // 18

This creates a closure because ? marks a missing argument. $add10AndX is the important variable, it holds the callable you can reuse. If the callable has strict parameter types, the closure keeps them, so you still get proper type errors.

You’ll also see this shine with callback heavy code.

<?php
 
$strings = ['hello world', 'hello php'];
 
$replaceHello = str_replace('hello', 'hi', ?);
 
$result = array_map($replaceHello, $strings);
 
var_dump($result);

str_replace('hello', 'hi', ?) returns a closure that expects the third argument. That closure can be passed directly into array_map(). Edge case: if you partially apply a callable that takes arguments by reference, the exact behavior depends on the RFC’s final rules, so verify against the RFC when using references.

RFC: https://wiki.php.net/rfc/partial_function_application_v2

clamp()

Status: Accepted

This proposes a native clamp() function that keeps a value inside a min/max range. If the value is below min, you get min. If it is above max, you get max.

<?php
 
$percent = 140;
 
echo clamp($percent, 0, 100); // 100

$percent is your input. 0 and 100 are inclusive bounds. If you accidentally pass min > max, clamp() is expected to throw a ValueError, so don’t rely on silent fixes.

RFC: https://wiki.php.net/rfc/clamp_v2

RFCs not yet accepted for PHP 8.6

Everything in this section is still draft or under discussion, so details can change or the proposal can be rejected. I’m describing what each RFC is trying to add, and where it would show up in your code if it lands.

func_get_args_by_name()

Status: Under Discussion

This proposes a new function that returns the current function’s arguments, but keeps parameter names as array keys for named arguments. Unlike func_get_args(), you don’t lose the names.

<?php
 
function greet(string $name, int $age, ...$extra): array
{
return func_get_args_by_name();
}
 
var_dump(greet(name: 'Alice', age: 30, 'x', 'y'));

The returned array should contain keys like name and age for the named arguments. Extra positional arguments remain numeric keys. Edge case: if you pass a parameter positionally, it will likely appear as a numeric key, so don’t assume everything is named.

RFC: https://wiki.php.net/rfc/func_get_args_by_name

Nullable and non-nullable cast operators

Status: Under Discussion

This proposes two new cast forms:

  • (?type) which lets null pass through as null, but still validates and coerces non null values using weak mode parameter coercion rules.
  • (!type) which rejects null and also rejects values that cannot be coerced cleanly.
<?php
 
$value = null;
 
var_dump((?int) $value); // null
 
try {
var_dump((!int) $value);
} catch (TypeError $e) {
echo $e->getMessage(), "
";
}

(?int) is meant for pipelines where null is a meaningful absence. (!int) is meant for places where you want an explicit failure instead of silent conversion. Edge case: the exact coercion rules are the key part, and they’re based on weak mode parameter rules rather than today’s very permissive casts.

RFC: https://wiki.php.net/rfc/nullable-not-nullable-cast-operator

Deprecate fuzzy scalar casts

Status: Under Discussion

This aims to deprecate “fuzzy” casts where PHP currently does lossy conversions without telling you. The classic example is a partially numeric string where PHP keeps the numeric prefix and discards the rest.

<?php
 
$raw = "123abc";
 
// Today this becomes 123.
// Under this RFC, this kind of cast is expected to raise a deprecation in PHP 8.6.
$value = (int) $raw;
 
var_dump($value);

If this RFC passes, the practical fix is simple: validate first, then cast.

<?php
 
$raw = "123abc";
 
if (!ctype_digit($raw)) {
throw new InvalidArgumentException('Expected digits only');
}
 
$value = (int) $raw;
var_dump($value);

ctype_digit() is strict: it only accepts strings made of digits. That means it rejects negative numbers and whitespace, so pick a validator that matches your input rules.

RFC: https://wiki.php.net/rfc/deprecate-fuzzy-and-null-casts

Deprecations for PHP 8.6

Status: Draft

This is an umbrella RFC that collects deprecations proposed for PHP 8.6. It’s structured so individual deprecations can be voted separately. Examples currently listed include deprecating passing objects to certain array and zlib functions, and deprecating strcoll() and SORT_LOCALE_STRING.

RFC: https://wiki.php.net/rfc/deprecations_php_8_6

Add values() to BackedEnum

Status: Under Discussion

This proposes a values() method on BackedEnum to return all backing values as an indexed array. If you’ve written enums and then immediately needed an array_map(fn($c) => $c->value, Status::cases()), this removes the boilerplate.

<?php
 
enum Status: string
{
case Active = 'active';
case Inactive = 'inactive';
}
 
var_dump(Status::values());

If the enum already defines its own values() method, that should keep working. If you rely on a specific sort order, confirm what the RFC guarantees (it’s usually declaration order).

RFC: https://wiki.php.net/rfc/add_values_method_to_backed_enum

Stringable enums

Status: Under Discussion

This proposes allowing __toString() on enums. That would make it legal to directly echo an enum case with custom formatting.

<?php
 
enum Role: string
{
case Admin = 'admin';
 
public function __toString(): string
{
return $this->value;
}
}
 
echo Role::Admin;

This is intentionally narrow: it’s about letting enums define __toString(), not about adding state to enums.

RFC: https://wiki.php.net/rfc/stringable-enums

Stream error handling improvements

Status: Under Discussion

This proposes making stream errors more consistent and more programmatically usable. The RFC describes adding structured error storage, optional exception based behavior, and consistent error codes across wrappers. If you’ve ever had to juggle warnings, error handlers, and inconsistent messages from different stream wrappers, this is aiming at that pain.

RFC: https://wiki.php.net/rfc/stream_errors

Data encoding API

Status: Under Discussion

This proposes a standard encoding and decoding API for common base encodings. The motivation is to cover more variants than today’s base64_encode() and base64_decode(), including RFC 4648 family details and additional popular encodings.

RFC: https://wiki.php.net/rfc/data_encoding_api

Namespace-scoped visibility

Status: Under Discussion

This proposes a new visibility level, written like private(namespace), that allows access from within the same namespace. The goal is to share internal APIs between closely related classes without exposing them as public to the whole application.

RFC: https://wiki.php.net/rfc/namespace_visibility

PDO disconnect() and isConnected()

Status: Under Discussion

This proposes two methods on PDO:

  • PDO::disconnect() to explicitly close the underlying connection.
  • PDO::isConnected() to query whether the connection is currently established.

If this lands, it gives you a supported way to drop a connection without relying on unset($pdo) and garbage collection timing.

RFC: https://wiki.php.net/rfc/pdo_disconnect

Object-oriented curl API v2

Status: Under Discussion

PHP has curl handles as objects today, but they are still used mostly through procedural functions. This RFC proposes a real object oriented API on top of curl objects, with a cleaner structure and better type safety.

RFC: https://wiki.php.net/rfc/curl_oop_v2

num_available_processors()

Status: Under Discussion

This proposes a native function to get the number of available processors. It’s mainly useful for parallel work scheduling, like choosing a default worker count.

<?php
 
$workers = num_available_processors() ?? 1;
 
echo "Workers: {$workers}
";

The ?? 1 fallback matters because the RFC allows returning null in some situations. Don’t assume it always matches CPU affinity limits unless the RFC explicitly guarantees it.

RFC: https://wiki.php.net/rfc/num_available_processors

Drop 32-bit builds

Status: Under Discussion

This proposes stopping official 32-bit builds. If you’re deploying to very old systems this can be a breaking change, but most modern hosting and containers are already 64-bit.

RFC: https://wiki.php.net/rfc/drop_32bit_support

JSON Schema validation support

Status: Under Discussion

This proposes adding JSON Schema support to the JSON extension. The RFC describes schema objects (created from schema text) and validation integrated with existing JSON error handling. If you validate API payloads against schemas today using libraries, this would be a standard option.

RFC: https://wiki.php.net/rfc/json_schema_validation

pack()/unpack() endianness modifiers for signed integers

Status: Under Discussion

This proposes extending pack() and unpack() format strings to support endianness modifiers on signed integer formats. The goal is to avoid manual bit shifting when you need signed little endian or big endian integers.

RFC: https://wiki.php.net/rfc/pack-unpack-endianness-signed-integers-support

Context managers

Status: In Discussion

This proposes a using (...) { ... } style construct to guarantee cleanup at the end of a block. The core idea is “acquire something, run code, always release it”, without manually writing try/finally in every place. The RFC examples focus on file handles and transactions.

RFC: https://wiki.php.net/rfc/context-managers

True Async

Status: Under discussion

This is a broader proposal to define a standard async model and engine level support that extensions can hook into. It includes a base RFC and related RFCs for scope and an engine API. This is ambitious, and it’s the kind of RFC that can take multiple release cycles if it lands at all.

RFC: https://wiki.php.net/rfc/true_async

True Async engine API

Status: Under discussion

This is a companion RFC that focuses on an engine level API for pluggable schedulers, reactors, and thread pools. Think of it as infrastructure to make async implementations possible without hard-wiring PHP to one event loop.

RFC: https://wiki.php.net/rfc/true_async_engine_api

True Async scope and structured concurrency

Status: Under discussion

This extends the True Async proposal with scoped lifetimes for coroutines and structured concurrency concepts. The key idea is tying concurrent work to a scope so cancellation and cleanup are automatic when a scope ends.

RFC: https://wiki.php.net/rfc/true_async_scope

Conclusion

You now have a realistic release window for PHP 8.6 based on the recent late-November cadence. We covered the features already accepted or in implementation, including partial function application and clamp(). We grouped every other currently proposed RFC for PHP 8.6 that is still draft or under discussion, with a short description of what it would change. As votes happen, the only reliable source of truth is each RFC’s status, so keep an eye on which items move to Accepted or Implemented.

Nabil Hassen
Nabil Hassen
Full Stack Web Developer

Stay Updated.

I'll you email you as soon as new, fresh content is published.

Thanks for subscribing to my blog.

Latest Posts