A major update to the PHP language

New URI extension, modify properties while cloning, the Pipe operator, and more.

What's new in PHP 8.5

Add RFC 3986 and WHATWG URL compliant API

PHP < 8.5
                
                  
                    $components
                    
                    =
                    
                    parse_url
                    (
                    "https://php.net/releases/8.5/en.php"
                    )
                    ;
                  
                  
var_dump ( $components [ 'host' ] ) ; // string(7) "php.net"
PHP 8.5 New
                
                  
                    use
                    
                    Uri\Rfc3986\Uri
                    ;
                  
                  
                    $uri
                    
                    =
                    
                    new
                    
                    Uri
                    (
                    "https://php.net/releases/8.5/en.php"
                    )
                    ;
                  
                  
var_dump ( $uri -> getHost ( ) ) ; // string(7) "php.net"

As an always-available part of PHP's standard library the new URI extension provides APIs to parse and modify URIs and URLs according to the RFC 3986 and the WHATWG URL standards.

The secure and standards-compliant URI parsing is powered by the uriparser (RFC 3986) and Lexbor (WHATWG URL) libraries.

Clone with V2

PHP < 8.5
                
                  
                    final
                    
                    readonly
                    
                    class
                    
                    PhpVersion
                  
                  
                    {
                  
                  
                    
                    public
                    
                    function
                    
                    __construct
                    (
                  
                  
                    
                    
                    public
                    
                    string
                    
                    $version
                    
                    =
                    
                    'PHP 8.4'
                    ,
                  
                  
                    
                    )
                    
                    {}
                  
                  
public function withVersion ( string $version ): self { $newObject = clone $this ; $newObject -> version = $version ;
return $newObject ; } }
$version = new PhpVersion ( ) ;
var_dump ( $version -> version ) ; // string(7) "PHP 8.4"
var_dump ( $version -> withVersion ( 'PHP 8.5' ) -> version ) ; // Fatal error: Uncaught Error: Cannot modify readonly property PhpVersion::$version
PHP 8.5 New
                
                  
                    final
                    
                    readonly
                    
                    class
                    
                    PhpVersion
                  
                  
                    {
                  
                  
                    
                    public
                    
                    function
                    
                    __construct
                    (
                  
                  
                    
                    
                    public
                    
                    string
                    
                    $version
                    
                    =
                    
                    'PHP 8.4'
                    ,
                  
                  
                    
                    )
                    
                    {}
                  
                  
public function withVersion ( string $version ): self { return clone ( $this , [ 'version' => $version , ] ) ; } }
$version = new PhpVersion ( ) ;
var_dump ( $version -> version ) ; // string(7) "PHP 8.4"
var_dump ( $version -> withVersion ( 'PHP 8.5' ) -> version ) ; // string(7) "PHP 8.5"
var_dump ( $version -> version ) ; // string(7) "PHP 8.4"

It is now possible to update properties during object cloning by passing an associative array with the updated to the clone() function. This enables straight-forward support of the "with-er" pattern for readonly classes.

Pipe Operator

PHP < 8.5
                
                  
                    $input
                    
                    =
                    
                    'Some kind of string.'
                    ;
                  
                  
$output = strtolower ( str_replace ( [ '.' , '/' , '…' ] , '' , str_replace ( ' ' , '-' , trim ( $input ) ) ) ) ;
var_dump ( $output ) ; // string(19) "some-kind-of-string"
PHP 8.5 New
                
                  
                    $input
                    =
                    ' Some kind of string. '
                    ;
                  
                  
$output = $input |> trim ( ... ) |> ( fn ( $string ) => str_replace ( ' ' , '-' , $string ) ) |> ( fn ( $string ) => str_replace ( [ '.' , '/' , '…' ] , '' , $string ) ) |> strtolower ( ... ) ;
var_dump ( $output ) ; // string(19) "some-kind-of-string"

New #[\NoDiscard] attribute

PHP < 8.5
                
                  
                    function
                    
                    getPhpVersion
                    (
                    ):
                    
                    string
                  
                  
                    {
                  
                  
                    
                    return
                    
                    'PHP 8.4'
                    ;
                  
                  
                    }
                  
                  
getPhpVersion ( ) ; // No Errors
PHP 8.5 New
                
                  
                    #[
                    \NoDiscard
                    ]
                  
                  
                    function
                    
                    getPhpVersion
                    (
                    ):
                    
                    string
                  
                  
                    {
                  
                  
                    
                    return
                    
                    'PHP 8.5'
                    ;
                  
                  
                    }
                  
                  
getPhpVersion ( ) ; // Warning: The return value of function getPhpVersion() should either be used or intentionally ignored by casting it as (void)

By adding the #[\NoDiscard] attribute to a function, PHP will check whether the returned value is consumed and emit a warning if it is not. This allows to improve the safety of APIs where the returned value is important, but where it is easy to forget using the return value by accident.

The associated (void) cast can be used to indicate that a value is intentionally unused.

Closures and First Class Callables in constant expressions

PHP < 8.5
                
                  
                    final
                    
                    class
                    
                    CalculatorTest
                    
                    extends
                    
                    \
                    PHPUnit\Framework\TestCase
                  
                  
                    {
                  
                  
                    
                    #[
                    DataProvider
                    (
                    'subtractionProvider'
                    )
                    ]
                  
                  
                    
                    public
                    
                    function
                    
                    testSubtraction
                    (
                  
                  
                    
                    
                    int
                    
                    $minuend
                    ,
                  
                  
                    
                    
                    int
                    
                    $subtrahend
                    ,
                  
                  
                    
                    
                    int
                    
                    $result
                  
                  
                    
                    ):
                    
                    void
                  
                  
                    
                    {
                  
                  
                    
                    
                    $this
                    ->
                    assertSame
                    (
                  
                  
                    
                    
                    
                    $result
                    ,
                    
                  
                  
                    
                    
                    
                    Calculator
                    ::
                    subtract
                    (
                    $minuend
                    ,
                    
                    $subtrahend
                    )
                  
                  
                    
                    
                    )
                    ;
                  
                  
                    
                    }
                  
                  
public static function subtractionProvider ( ): iterable { for ( $i = -10 ; $i <= 10 ; $i ++ ) { yield [ $i , $i , 0 , $i ] ; yield [ $i , 0 , $i ] ; yield [ 0 , $i , - $i ] ; } } }
PHP 8.5 New
                
                  
                    final
                    
                    class
                    
                    CalculatorTest
                  
                  
                    {
                  
                  
                    
                    #[
                    Test\CaseGenerator
                    (
                    static
                    
                    function
                    
                    (
                    ):
                    
                    iterable
                    
                    {
                  
                  
                    
                    
                    for
                    
                    (
                    $i
                    
                    =
                    
                    -10
                    ;
                    
                    $i
                    
                    <=
                    
                    10
                    ;
                    
                    $i
                    ++
                    )
                    
                    {
                  
                  
                    
                    
                    
                    yield
                    
                    [
                    $i
                    ,
                    
                    $i
                    ,
                    
                    0
                    ,
                    
                    $i
                    ]
                    ;
                  
                  
                    
                    
                    
                    yield
                    
                    [
                    $i
                    ,
                    
                    0
                    ,
                    
                    $i
                    ]
                    ;
                  
                  
                    
                    
                    
                    yield
                    
                    [
                    0
                    ,
                    
                    $i
                    ,
                    
                    -
                    $i
                    ]
                    ;
                  
                  
                    
                    
                    }
                  
                  
                    
                    }
                    )
                    ]
                  
                  
                    
                    public
                    
                    function
                    
                    testSubtraction
                    (
                  
                  
                    
                    
                    int
                    
                    $minuend
                    ,
                  
                  
                    
                    
                    int
                    
                    $subtrahend
                    ,
                  
                  
                    
                    
                    int
                    
                    $result
                  
                  
                    
                    )
                  
                  
                    
                    {
                  
                  
                    
                    
                    \
                    assert
                    (
                  
                  
                    
                    
                    
                    Calculator
                    ::
                    subtract
                    (
                    $minuend
                    ,
                    
                    $subtrahend
                    )
                    
                    ===
                    
                    $result
                  
                  
                    
                    
                    )
                    ;
                  
                  
                    
                    }
                  
                  
                    }
                  
                
              

Persistent cURL share handle improvement

PHP < 8.5
                
                  
                    $sh
                    
                    =
                    
                    curl_share_init
                    (
                    )
                    ;
                  
                  
                    curl_share_setopt
                    (
                    $sh
                    ,
                    
                    CURLSHOPT_SHARE
                    ,
                    
                    CURL_LOCK_DATA_DNS
                    )
                    ;
                  
                  
                    curl_share_setopt
                    (
                    $sh
                    ,
                    
                    CURLSHOPT_SHARE
                    ,
                    
                    CURL_LOCK_DATA_CONNECT
                    )
                    ;
                  
                  
$ch1 = curl_init ( 'https://php.net/' ) ; curl_setopt ( $ch1 , CURLOPT_SHARE , $sh ) ; curl_exec ( $ch1 ) ;
$ch2 = curl_init ( 'https://thephp.foundation/' ) ; curl_setopt ( $ch2 , CURLOPT_SHARE , $sh ) ; curl_exec ( $ch2 ) ;
PHP 8.5 New
                
                  
                    $sh
                    
                    =
                    
                    curl_share_init_persistent
                    (
                    [
                  
                  
                    
                    CURL_LOCK_DATA_DNS
                    ,
                  
                  
                    
                    CURL_LOCK_DATA_CONNECT
                  
                  
                    ]
                    )
                    ;
                  
                  
$ch1 = curl_init ( 'https://php.net/' ) ; curl_setopt ( $ch1 , CURLOPT_SHARE , $sh ) ; curl_exec ( $ch1 ) ;
$ch2 = curl_init ( 'https://thephp.foundation/' ) ; curl_setopt ( $ch2 , CURLOPT_SHARE , $sh ) ; curl_exec ( $ch2 ) ;

New classes available: CurlSharePersistentHandle class, curl_multi_get_handles() and curl_share_init_persistent() functions are available.

New array_first() and array_last() functions

PHP < 8.5
                
                  
                    $php
                    
                    =
                    
                    [
                  
                  
                    
                    'php-82'
                    
                    =>
                    
                    [
                    'state'
                    
                    =>
                    
                    'security'
                    ,
                    
                    'branch'
                    
                    =>
                    
                    'PHP-8.2'
                    ]
                    ,
                  
                  
                    
                    'php-83'
                    
                    =>
                    
                    [
                    'state'
                    
                    =>
                    
                    'active'
                    ,
                    
                    'branch'
                    
                    =>
                    
                    'PHP-8.3'
                    ]
                    ,
                  
                  
                    
                    'php-84'
                    
                    =>
                    
                    [
                    'state'
                    
                    =>
                    
                    'active'
                    ,
                    
                    'branch'
                    
                    =>
                    
                    'PHP-8.4'
                    ]
                    ,
                  
                  
                    
                    'php-85'
                    
                    =>
                    
                    [
                    'state']
                    
                    =>]
                    
                    'upcoming'
                    ,
                    
                    'branch'
                    
                    =>
                    
                    'PHP-8.5'
                    ]
                    ,
                  
                  
                    ]
                    ;
                  
                  
$upcomingRelease = null ; foreach ( $php as $key => $version ) { if ( $version [ 'state' ] === 'upcoming' ) { $upcomingRelease = $version ; break ; } }
var_dump ( $upcomingRelease ) ;
PHP 8.5 New
                
                  
                    $php
                    
                    =
                    
                    [
                  
                  
                    
                    'php-82'
                    
                    =>
                    
                    [
                    'state'
                    
                    =>
                    
                    'security'
                    ,
                    
                    'branch'
                    
                    =>
                    
                    'PHP-8.2'
                    ]
                    ,
                  
                  
                    
                    'php-83'
                    
                    =>
                    
                    [
                    'state'
                    
                    =>
                    
                    'active'
                    ,
                    
                    'branch'
                    
                    =>
                    
                    'PHP-8.3'
                    ]
                    ,
                  
                  
                    
                    'php-84'
                    
                    =>
                    
                    [
                    'state'
                    
                    =>
                    
                    'active'
                    ,
                    
                    'branch'
                    
                    =>
                    
                    'PHP-8.4'
                    ]
                    ,
                  
                  
                    
                    'php-85'
                    
                    =>
                    
                    [
                    'state'
                    
                    =>
                    
                    'upcoming'
                    ,
                    
                    'branch'
                    
                    =>
                    
                    'PHP-8.5'
                    ]
                    ,
                  
                  
                    ]
                    ;
                  
                  
$upcomingRelease = array_first ( array_filter ( $php , static fn ( $version ) => $version [ 'state' ] === 'upcoming' ) ) ;
var_dump ( $upcomingRelease ) ;

New Classes, Interfaces, and Functions

  • Property Promotion is now available for final
  • Attributes are now available for constants.
  • Attribute #[\Override] now works on properties
  • Attribute #[\Deprecated] available for traits
  • Asymmetric Visibility for Static Properties
  • New #[\DelayedTargetValidation] attribute is available
  • New get_error_handler(), get_exception_handler() functions are available.
  • New Closure::getCurrent method is available.
  • New Dom\Element::getElementsByClassName() and Dom\Element::insertAdjacentHTML() methods are available.
  • New enchant_dict_remove_from_session() and enchant_dict_remove() functions are available.
  • New grapheme_levenshtein() function is available.
  • New opcache_is_script_cached_in_file_cache() function is available.
  • New ReflectionConstant::getFileName(), ReflectionConstant::getExtension(), ReflectionConstant::getExtensionName(), ReflectionConstant::getAttributes(), and ReflectionProperty::getMangledName() methods are available.

Deprecated Classes, Interfaces, and Functions

  • No deprecations or breaking changes.

Better performance, better syntax, improved type safety.

Upgrade to PHP 8.5 now

The migration guide is available in the PHP Manual. Please consult it for a detailed list of new features and backward-incompatible changes.