PHP 8.6 is in beta and is scheduled to reach general availability on November 19, 2026. Alpha 1 through Alpha 3 ran from July 2 to July 30, 2026. Beta 1 with a soft feature freeze arrived on August 13, Beta 3 on September 10, the feature freeze is set for September 22, RC 1 for September 24, and RC 4 for November 5. Daniel Scherzer, Matteo Beccati, and Joe Ferguson are the release managers.

clamp.php
<?php
echo clamp(10, min: 0, max: 100), PHP_EOL;
echo clamp(101, min: 0, max: 100), PHP_EOL;
echo clamp(-1, min: 0, max: 100), PHP_EOL;

Partial function application creates a closure from a function with some arguments already supplied. The `?` placeholder represents one argument supplied later, while `...` covers all remaining arguments. The closure preserves the original parameter names, types, and defaults, and supplied values are evaluated when the closure is created. A follow-up RFC makes every `?` parameter required on the resulting closure, even when the original parameter was optional. The earlier proposal failed in 2021, while Partial Function Application v2 passed unanimously with 33 votes.

The new `clamp()` function returns a value within given bounds or the closest bound outside them. It supports comparable values such as strings and `DateTime` objects. A `$min` value greater than `$max` raises `ValueError`. The function provides a direct alternative to the commonly used `min(max($value, $min), $max)` expression.

PHP 8.6 adds `Time\Duration`, a final readonly class for stopwatch-style intervals with nanosecond precision. It offers unit-specific factory methods, arithmetic, comparisons, and construction from ISO 8601 duration strings. Core functions and the new polling API can use it as a shared type for durations that were previously represented by loose integers or floats.

Readonly properties may now have default values. PHP versions before 8.6 rejected this at compile time, which complicated fixed implementations of get-only interface properties introduced with PHP 8.4. A declaration such as `CreateBooksTable implements Migration` can now assign `2026_01_01_create_books_table` to its readonly `$name` property. Readonly reassignment rules remain unchanged.

Function parameters can carry their own doc comments. `ReflectionParameter::getDocComment()` exposes those comments to tools, so documentation for parameters such as `$query` and `$limit = 10` no longer needs a repeated parameter name in a function-level `@param` tag. IDEs and static analyzers can read the annotations directly.

The `Io\Poll` namespace provides one polling interface for `epoll` on Linux, `kqueue` on BSD and macOS, event ports on Solaris, and `WSAPoll` on Windows. Userland event loops and asynchronous runtimes can use `Context`, `Event`, and `StreamPollHandle` with nonblocking sockets, replacing `stream_select()` in this area. The primary motivation is internal signal handling and FPM work, with asynchronous frameworks as a secondary audience.

A global `SortDirection` enum defines `Ascending` and `Descending`. Core APIs do not consume it yet, but libraries can share the type and query builders can use it for ordering. Enums can also implement `__debugInfo()`. PHP 8.6 lifts the earlier restriction because this method needs no object state, allowing customized `var_dump()` output.

Streams receive a unified error model. The `error_mode` stream context option selects warnings, exceptions, or silence. `stream_last_errors()` returns structured `StreamError` objects, and `StreamException` exposes collected errors with codes from the `StreamErrorCode` enum, which contains more than 50 semantic codes. The model covers operations such as opening `/nonexistent/file.txt` with `StreamErrorMode::Exception`.

The URI extension from PHP 8.5 gains builder classes. `Uri\Rfc3986\UriBuilder` can assemble an `https` URI for `example.com` with the path `/foo/bar` through chained setters. The URI follow-up also adds `getUriType()`, `getHostType()`, and percent-encoding functions for individual URI components.

New installations receive stricter native session defaults. `session.use_strict_mode` changes from `0` to `1`, `session.cookie_httponly` from `0` to `1`, and `session.cookie_samesite` from unset to `Lax`. Laravel manages its own session cookies, so most Laravel applications are unaffected. Applications using native PHP sessions and depending on the former defaults need to review the session security defaults RFC. The PHP 8.6 preparation page, accepted RFC index, and deprecations list provide the remaining release details.