PHP 8.5 Stable Release: 'Clone With', #[NoDiscard], and New URL Classes Define the Future
PHP 8.5 is no longer just on the horizon; it’s here. With its stable release confirmed for November 20, 2025, and now in its Release Candidate (RC) phase, developers worldwide are getting their first hands-on experience with an update that solidifies PHP's commitment to clean code, immutability, and robust developer tooling. While earlier previews highlighted quality-of-life improvements, the final sprint to release has unveiled some truly transformative features that promise to significantly refine the PHP development experience.
This article takes a fresh look at PHP 8.5, focusing on the most impactful additions, re-evaluating earlier observations, and reminding us of crucial deprecations.
The Big Three: Game-Changing Additions in PHP 8.5 🚀
While a host of improvements land with 8.5, three features stand out as particularly significant for modern PHP development:
clone with
Expression: Embracing Immutability
1. The Perhaps the most anticipated and impactful new syntax is the clone with
expression.
For years, working with immutable objects, especially those leveraging PHP 8.1’s
readonly` properties, presented a common challenge: how do you "update" a specific property on an object without violating its immutability? The answer often involved awkward workarounds or boilerplate code.
PHP 8.5 solves this elegantly:
1class User 2{ 3 public function __construct( 4 public readonly int $id, 5 public readonly string $name, 6 public readonly string $email 7 ) {} 8} 9 11 12// Old way (pre-PHP 8.5): cumbersome for readonly properties13// $newUser = new User($user->id, 'Bob', $user->email);14 15// PHP 8.5: Clean and concise!16$updatedUser = clone $user with ['name' => 'Bob'];17 18var_dump($updatedUser->name); // string(3) "Bob"19var_dump($user->name); // string(5) "Alice" - original is untouched
This syntax allows you to clone an object and, in the same breath, override specific properties in the newly created clone. It’s a powerful pattern for functional programming and makes working with immutable data structures a joy.
#[NoDiscard]
Attribute: Preventing Accidental Bugs
2. The Silent failures are often the hardest to debug. The #[NoDiscard]
attribute is PHP 8.5's answer to a common class of these: ignoring the return value of a function that produces a result.
By marking a function or method with
#[NoDiscard]`, you instruct PHP to warn the developer if its return value is not explicitly used.
1class StringHelper 2{ 3 #[NoDiscard] 4 public static function clean(string $text): string 5 { 6 return trim(strip_tags($text)); 7 } 8 9 public static function process(string $text): void10 {11 // ... some processing that doesn't return a value12 }13}14 15$dirtyInput = " <h1>Hello World!</h1> ";16 17StringHelper::clean($dirtyInput); // PHP 8.5 Warning: The return value of StringHelper::clean() is not used.18// This would be the correct usage:19$cleaned = StringHelper::clean($dirtyInput);20echo $cleaned; // Hello World!21 22StringHelper::process("some text"); // No warning, as process() returns void.
This attribute is invaluable for pure functions, builder patterns, or any method where the returned value is crucial for the program's correctness. It’s a proactive safety net that catches potential bugs at development time.
3. New URL Handling Classes: Modern Web Standards at Your Fingertips
The internet runs on URLs, but PHP's built-in parse_url()
function, while functional, has long been a source of frustration due to its inconsistencies and deviations from modern standards. PHP 8.5 introduces a suite of new, dedicated, and read-only classes for parsing and manipulating URIs and URLs, adhering strictly to RFC 3986 and the WHATWG URL Standard.
`
While specific class names are still stabilizing, the intent is clear: to provide robust, object-oriented, and standard-compliant tools for URL management.
1use Uri\WhatWg\Url; // Example class name, actual may vary slightly 2 4 5echo $url->host; // www.example.com 6echo $url->port; // 8080 7echo $url->pathname; // /path/to/page 8echo $url->search; // ?query=string 9echo $url->hash; // #fragment10echo $url->username; // user11// ... and many more properties and methods
These classes offer a predictable and safe way to handle complex URL structures, crucial for secure and interoperable web applications, moving beyond the quirks of parse_url()
.
Other Notable Enhancements & Quality-of-Life Improvements ✨
Beyond the big three, PHP 8.5 brings a host of other valuable features:
- Pipe Operator (
|>
): As noted in earlier previews, this is still a highly anticipated feature for chaining function calls in a more readable, left-to-right fashion.'Hello World' |> strtoupper(...) |> trim(...)
makes data flow intuitive. - New Array Functions (
array_first()
andarray_last()
): Complementingarray_key_first()
andarray_key_last()
, these new functions simplify retrieving the first or last value of an array directly. - Better Error and Exception Handling:
get_error_handler()
andget_exception_handler()
now allow retrieval of active custom handlers, aiding debugging and framework development. Stack traces for fatal errors provide crucial context. max_memory_limit
INI Directive: A new system-level INI directive that sets an absolute maximum for thememory_limit
, preventing individual scripts from requesting excessive memory even ifmemory_limit
is increased at runtime. Essential for stable shared hosting and container environments.IntlListFormatter
Class: A welcome addition to theIntl
extension for correctly formatting lists (e.g., "A, B, and C") according to locale-specific grammatical rules.- CLI Improvement:
php --ini=diff
: A handy new command-line flag that outputs only the INI directives that differ from PHP's default settings, making configuration debugging much faster. - Closures in Constant Expressions: Enables the use of
static fn(...) => ...
within class constant declarations or as default values for promoted properties, offering more flexibility for constant definitions. - New cURL Function (
curl_multi_get_handles()
): For those managing multiple asynchronous cURL requests, this function simplifies handle management and debugging. - Internationalization Features: The
Intl
extension receiveslocale_is_right_to_left()
(andLocale::isRightToLeft()
), aiding applications supporting RTL languages.
Deprecations and Backward Compatibility Issues ⚠️
As PHP matures, legacy features are retired. While PHP 8.5 continues this trend, the changes are manageable for most:
- Deprecation of MHASH constants: Transition to the more modern and secure alternatives provided by the Hash extension.
- Deprecation of non-string values from output handlers: Output handlers should strictly return string values for predictable behavior.
- Deprecated custom output buffer handlers: Emitting output from custom output buffer handlers is now discouraged in favor of standard mechanisms.
Performance and Outlook ⚡
PHP 8.5 continues the tradition of incremental performance enhancements. While not a revolutionary leap over 8.4, the ongoing optimizations within the Just-In-Time (JIT) compiler and continued core engine improvements contribute to a faster and more memory-efficient language. These gains, however small individually, sum up to a more performant platform for large-scale applications.
The stable release of PHP 8.5 on November 20, 2025, marks another significant milestone for the language. It reinforces PHP's strategic focus on developer experience, robust tooling, and modern coding paradigms. Developers are encouraged to begin testing their applications against the Release Candidate versions to ensure a smooth upgrade path and to fully leverage the powerful new features that promise cleaner, more maintainable, and more expressive PHP code.