$ cat whats-new-in-php-86-2.md
What’s new in PHP 8.6
A look at what PHP 8.6 brings so far, including explicit endianness for pack() and unpack(), stream error handling via contexts, writes to object properties referenced by constants, a stream filter chain limit, and #[\Override] for class constants. Details may still change before the November 2026 release.
amitmerchant.com06 Nov 2026 · 7 min read · summary
Read on www.amitmerchant.com ↗PHP 8.5 has brought us features such as the pipe operator, array_first(), array_last(), the URI extension, and the #[\NoDiscard] attribute.
PHP 8.6 is shaping up to be another interesting release. It contains a mix of language improvements, new standard-library functions, better networking APIs, security improvements, and a few useful internal optimizations. It’s general availability is currently scheduled for November 19, 2026.
So, it’s a good time to look at everything that has made it into PHP 8.6 so far.
This article is based on the features currently listed in PHP’s implemented PHP 8.6 RFCs. Some details may still change before the final release but it should largely remain the same.
Direction-aware property resolution
Explicit endianness for pack() and unpack()
Signed integers
Floating-point values
Better stream error handling
Writing to object properties referenced by constants
A limit for stream filter chains
#[\Override] for class constants
Deprecating return values from constructors and destructors
New locale display helpers
A new polling API
Debuggable enums
More secure session defaults
Deprecating mbregex
The SortDirection enum
DocComments for function parameters
Form Feed support in trim functions
grapheme_strrev()
The clamp() function
is_readable() and is_writable() reflection methods
mysqli_quote_string()
TLS session resumption for streams
Displaying function arguments in errors
Partial function application
The Duration class
Closure optimizations
Readonly property defaults
SNMP improvements
In Closing
Direction-aware property resolution
The Direction-Aware Property Resolution RFC is an engine-level improvement for asymmetric properties introduced in PHP 8.4.
Asymmetric visibility lets you make a property publicly readable but restrict who can modify it:
class User
{
public private(set) string $name;
}
The property can be read from outside the class, but it can only be changed inside the class.
Previously, PHP had to check the write visibility every time the property was modified. That made writes to private(set) and protected(set) properties more expensive than writes to ordinary public properties.
PHP 8.6 moves this check to the runtime-cache population phase. Once PHP knows that a particular call site has write access, subsequent writes can use the cached result.
The syntax does not change. The improvement is mostly invisible to application code, but it makes asymmetric properties cheaper to use, especially in loops, object hydration, serializers, and builders.
class Counter
{
public private(set) int $value = 0;
public function increment(): void
{
$this->value++;
}
}
This is a performance improvement rather than a new language feature. Existing behavior remains the same.
Explicit endianness for pack() and unpack()
PHP 8.6 extends the format-string syntax used by pack() and unpack().
Signed integers
Until now, PHP supported machine-endian signed integers, but not signed integers with an explicitly chosen byte order.
PHP 8.6 adds < and > modifiers:
$bytes = pack('s<l<q<', -258, -16909060, -72340172838076673);
The modifiers mean:
s< — signed 16-bit little-endian integer
s> — signed 16-bit big-endian integer
l< — signed 32-bit little-endian integer
l> — signed 32-bit big-endian integer
q< — signed 64-bit little-endian integer
q> — signed 64-bit big-endian integer
They also work with unsigned machine-endian formats:
$bytes = pack('S<L>Q<', 258, 16909060, 72340172838076673);
This is particularly useful when working with binary protocols and file formats.
Existing format codes such as v, n, V, and N continue to work as before. Applying an endianness modifier to a format that already has an inherent byte order throws a ValueError.
Floating-point values
The same syntax is also being added for floating-point values through the floating-point endianness RFC:
$bytes = pack('f<d>', 3.14159, 2.71828);
The supported formats are:
f< — little-endian single-precision float
f> — big-endian single-precision float
d< — little-endian double-precision float
d> — big-endian double-precision float
For example:
$bytes = pack('f>d>', 3.14159, 2.71828);
[$float, $double] = array_values(
unpack('f<a/d<b', $bytes)
);
The new syntax is equivalent to the existing format letters:
pack('f<', 3.14) === pack('g', 3.14);
pack('f>', 3.14) === pack('G', 3.14);
pack('d<', 3.14) === pack('e', 3.14);
pack('d>', 3.14) === pack('E', 3.14);
Better stream error handling
PHP stream operations have historically reported errors in several different ways. Depending on the stream wrapper and operation, you might get a warning, a notice, a failed return value, or no particularly useful structured information at all.
The Stream Error Handling Improvements RFC introduces a more consistent model.
A stream context can now define how errors should be handled:
$context = stream_context_create([
'stream' => [
'error_mode' => StreamErrorMode::Exception,
],
]);
The available modes are:
StreamErrorMode::Error — use normal PHP warnings and notices
StreamErrorMode::Exception — throw exceptions for terminating errors
StreamErrorMode::Silent — suppress error output
For example:
$context = stream_context_create([
'stream' => [
'error_mode' => StreamErrorMode::Exception,
],
]);
$content = file_get_contents('/path/to/missing-file', context: $context);
In exception mode, errors that prevent an operation from completing can throw a StreamException.
The RFC also adds structured error storage, error codes, and support for custom error callbacks. This should make stream-heavy applications easier to debug and easier to integrate with normal exception-based error handling.
The new behavior must be enabled through an explicit context. It cannot be applied globally through the default stream context, which helps preserve compatibility with existing applications.
Writing to object properties referenced by constants
PHP constants cannot contain arrays that are modified in place, but an object stored in a constant is still a mutable object.
PHP 8.6 allows property operations on objects referenced by constants, as described in the Const Object Property Write RFC.
const CONFIG = new stdClass();
CONFIG->environment = 'production';
CONFIG->debug = false;
The constant binding itself remains immutable. You cannot make CONFIG refer to a different object, but you can modify the object it points to.
The change also covers related operations:
CONFIG->counter++;
isset(CONFIG->debug);
unset(CONFIG->debug);
CONFIG->name .= ' application';
This is intentionally limited to objects. Array constants remain immutable.
A limit for stream filter chains
Stream filters can be chained together:
$stream = fopen('php://memory', 'w+');
stream_filter_append($stream, 'string.toupper');
stream_filter_append($stream, 'string.rot13');
Because filters can be created dynamically, an application could previously build an unnecessarily large filter chain. PHP 8.6 adds a maximum number of filters that can be attached to a stream through the Limit Maximum Number of Filter Chains RFC.
This gives PHP a defensive upper bound and helps reduce the risk of excessive memory usage or denial-of-service scenarios caused by unbounded filter creation.
Normal applications should not need to change anything. The limit mainly protects code that accepts filter configuration from untrusted input.
#[\Override] for class constants
PHP 8.3 introduced the #[\Override] attribute for methods. PHP 8.6 extends it to class constants through the Override for Class Constants RFC.
class Base
{
protected const TYPE = 'base';
}
class Child extends Base
{
#[\Override]
public const TYPE = 'child';
}
If the parent class or interface does not contain a matching constant, PHP reports an error:
class Example
{
#[\Override]
public const VALUE = 123;
}
This is useful when a class intentionally overrides a constant from a parent class or interface. It allows PHP to catch typos and accidental API changes early.
The attribute also works with enum cases, since enum cases are internally represented as class constants.
Deprecating return values from constructors and destructors
Constructors and destructors do not return values. Nevertheless, PHP has historically allowed code like this:
class Example
{
public function __construct()
{
return 123;
}
}
The value is ignored, which can be confusing. PHP 8.6 deprecates returning a value from __construct() and __destruct() through the Deprecate Return Value from Construct RFC.
class Example
{
public function __construct()
{
return 123; // Deprecated
}
public function __destruct()
{
return 456; // Deprecated
}
}
A bare return; remains valid because it can be used to exit a constructor or destructor early:
public function __construct()
{
if (!$this->shouldInitialize()) {
return;
}
$this->initialize();
}
The deprecation is intended to prepare code for a future version of PHP where returning a value from these methods will become an error.
New locale display helpers
The Locale display keyword RFC adds two methods to the Locale class:
Locale::getDisplayKeyword(string $keyword, ?string $displayLocale = null): string|false
Locale::getDisplayKeywordValue(
string $keyword,
string $value,
?string $displayLocale = null
): string|false
They can be used to display locale keywords and values in a human-readable language.
echo Locale::getDisplayKeyword('collation', 'en');
// Collation
echo Locale::getDisplayKeywordValue('collation', 'phonebook', 'en');
// Phonebook
Procedural aliases are also provided:
locale_get_display_keyword();
locale_get_display_keyword_value();
These methods are useful when building locale-aware settings screens or translating ICU locale metadata.
A new polling API
PHP has had stream_select() for monitoring streams, but it has limitations and does not expose the richer polling facilities available on modern operating systems.
PHP 8.6 i
source
This is a summary of an article first published by amitmerchant.com. The full piece is on their site.