PHP 8.5 UPGRADE NOTES

1. Backward Incompatible Changes
2. New Features
3. Changes in SAPI modules
4. Deprecated Functionality
5. Changed Functions
6. New Functions
7. New Classes and Interfaces
8. Removed Extensions and SAPIs
9. Other Changes to Extensions
10. New Global Constants
11. Changes to INI File Handling
12. Windows Support
13. Other Changes
14. Performance Improvements

========================================
1. Backward Incompatible Changes
========================================

- Core:
  . It is no longer possible to use "array" and "callable" as class alias names
    in class_alias().
  . Loosely comparing uncomparable objects (e.g. enums, \CurlHandle and other
    internal classes) to booleans was previously inconsistent. If compared to a
    boolean literal $object == true, it would behave the same way as (bool)
    $object. If compared to a statically unknown value $object == $true, it
    would always return false. This behavior was consolidated to always follow
    the behavior of (bool) $object.
  . The return value of gc_collect_cycles() no longer includes strings and
    resources that were indirectly collected through cycles.
  . It is now allowed to substitute static with self or the concrete class name
    in final subclasses.
  . The tick handlers are now deactivated after all shutdown functions, destructors
    have run and the output handlers have been cleaned up.
    This is a consequence of fixing GH-18033.
  . Traits are now bound before the parent class. This is a subtle behavioral
    change, but should more closely match user expectations, demonstrated by
    GH-15753 and GH-16198.
  . Errors emitted during compilation and class linking are now always delayed
    and handled after compilation or class linking. Fatal errors emitted during
    compilation or class linking cause any delayed errors to be handled
    immediately, without calling user-defined error handlers.
  . Exceptions thrown by user-defined error handlers when handling class linking
    errors are not promoted to fatal errors anymore and do not prevent linking.
  . Applying #[\Attribute] to an abstract class, enum, interface, or trait triggers
    an error during compilation. Previously, the attribute could be added, but when
    ReflectionAttribute::newInstance() was called an error would be thrown.
    The error can be delayed from compilation to runtime using the new
    #[\DelayedTargetValidation] attribute.
  . The disable_classes INI setting has been removed as it causes various
    engine assumptions to be broken.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#remove_disable_classes_ini_setting
  . Destructuring non-array values (other than NULL) using [] or list() now
    emits a warning.
    RFC: https://wiki.php.net/rfc/warnings-php-8-5#destructuring_non-array_values
  . A warning is now emitted when casting floats (or strings that look like
    floats) to int if they cannot be represented as one. This affects explicit
    int casts and implicit int casts.
    RFC: https://wiki.php.net/rfc/warnings-php-8-5#casting_out_of_range_floats_to_int
  . A warning is now emitted when casting NAN to other types.
    RFC: https://wiki.php.net/rfc/warnings-php-8-5#coercing_nan_to_other_types

- BZ2:
  . bzcompress() now throws a ValueError when $block_size is not between
    1 and 9.
  . bzcompress() now throws a ValueError when $work_factor is not between
    0 and 250.

- DOM:
  . Cloning a DOMNamedNodeMap, DOMNodeList, Dom\NamedNodeMap, Dom\NodeList,
    Dom\HTMLCollection, and Dom\DtdNamedNodeMap now fails.
    This never actually resulted in a working object,
    so the impact should actually be zero.

- FileInfo:
  . finfo_file() and finfo::file() now throws a ValueError instead of a
    TypeError when $filename contains nul bytes.
    This aligns the type of Error thrown to be consistent with the rest of
    the language.

- Intl:
  . The extension now requires at least ICU 57.1.
  . The behaviour of Collator::SORT_REGULAR with respect to handling numeric
    strings is now aligned with the behaviour of SORT_REGULAR in ext/standard.
    This is a consequence of fixing bug GH-18566.

- LDAP:
  . ldap_get_option() and ldap_set_option() now throw a ValueError when
    passing an invalid option.

- MBstring:
  . Unicode data tables have been updated to Unicode 17.0

- MySQLi:
  . Calling the mysqli constructor on an already-constructed object
    is now no longer possible and throws an Error.

- ODBC:
  . ODBC now assumes that at least ODBC 3.5 functionality is available. The
    ODBCVER definition and build system flags to control it have been removed.
  . ODBC no longer has build flags to build against specific drivers (except
    for DB2) and removes special cases for those drivers. It is strongly
    recommended to use a driver manager like iODBC or unixODBC on non-Windows.

- Opcache:
  . The Opcache extension is now always built into the PHP binary and is always
    loaded. The INI directives opcache.enable and opcache.enable_cli are still
    honored.
    The --enable-opcache/--disable-opcache configure flags have been removed,
    and the build does not produce opcache.so or php_opcache.dll objects
    anymore.
    Using zend_extension=opcache.so or zend_extension=php_opcache.dll INI
    directives will emit a warning.

- PCNTL:
  . pcntl_exec() now throws ValueErrors when entries of the $args parameter
    contain null bytes.
  . pcntl_exec() now throws ValueErrors when entries or keys of the
    $env_vars parameter contain null bytes.

- PCRE:
  . The extension is compiled without semi-deprecated
    PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK compile option.
    https://github.com/PCRE2Project/pcre2/issues/736#issuecomment-2754024651

- PDO:
  . The constructor arguments set in conjunction with PDO::FETCH_CLASS now
    follow the usual CUFA (call_user_func_array) semantics.
    This means string keys will act like a named argument.
    Moreover, automatic wrapping for by-value arguments passed to a by-ref
    parameter has been removed, and the usual E_WARNING about this is now
    emitted.
    To pass a variable by-ref to a constructor argument use the general
    array value reference assignment: $ctor_args = [&$valByRef]
  . Attempting to call PDOStatement::setFetchMode during a call to PDO::fetch(),
    PDO::fetchObject(), PDO::fetchAll(),
    for example using tricks such as passing the statement object as a constructor
    argument when fetching into an object, will now throw an Error.
  . The value of the constants PDO::FETCH_GROUP, PDO::FETCH_UNIQUE,
    PDO::FETCH_CLASSTYPE, PDO::FETCH_PROPS_LATE, and PDO::FETCH_SERIALIZE
    have changed.
  . A ValueError is now thrown if PDO::FETCH_PROPS_LATE is used with a fetch
    mode different than PDO::FETCH_CLASS, consistent with other fetch flags.
  . A ValueError is now thrown if PDO::FETCH_INTO is used as a fetch mode in
    PDO::fetchAll(), similar to PDO::FETCH_LAZY.

- PDO_FIREBIRD:
  . A ValueError is now thrown when trying to set a cursor name that is too
    long on a PDOStatement resulting from the Firebird driver.

- Session:
  . Attempting to write session data where $_SESSION has a key containing
    the pipe character will now emit a warning instead of silently failing.

- SimpleXML:
  . Passing an XPath expression that returns something other than a node set
    to SimpleXMLElement::xpath() will now emit a warning and return false,
    instead of silently failing and returning an empty array.

- SPL:
  . ArrayObject no longer accepts enums, as modifying the $name or $value
    properties can break engine assumptions.
  . SplFileObject::fwrite's parameter $length is now nullable. The default
    value changed from 0 to null.

- Standard:
  . Using a printf-family function with a formatter that did not specify the
    precision previously incorrectly reset the precision instead of treating
    it as a precision of 0. See GH-18897.

- SOAP:
  . SoapClient::__doRequest() expects a new, optional $uriParserClass parameter
    as described in https://wiki.php.net/rfc/url_parsing_api#plugability.

========================================
2. New Features
========================================

- Core:
  . Closure is now a proper subtype of callable
  . Added support for Closures and first class callables in constant
    expressions.
    RFC: https://wiki.php.net/rfc/closures_in_const_expr
    RFC: https://wiki.php.net/rfc/fcc_in_const_expr
  . Fatal Errors (such as an exceeded maximum execution time) now include a
    backtrace.
    RFC: https://wiki.php.net/rfc/error_backtraces_v2
  . Added the #[\NoDiscard] attribute to indicate that a function's return
    value is important and should be consumed.
    RFC: https://wiki.php.net/rfc/marking_return_value_as_important
  . Added the (void) cast to indicate that not using a value is intentional.
    The (void) cast has no effect on the program's execution by itself, but
    it can be used to suppress warnings emitted by #[\NoDiscard] and possibly
    also diagnostics emitted by external IDEs or static analysis tools.
    RFC: https://wiki.php.net/rfc/marking_return_value_as_important
  . Added asymmetric visibility support for static properties.
    RFC: https://wiki.php.net/rfc/static-aviz
  . Added support for casts in constant expressions.
  . Added support for attributes on compile-time non-class constants.
    RFC: https://wiki.php.net/rfc/attributes-on-constants
  . The #[\Deprecated] attribute can now be used on constants.
    RFC: https://wiki.php.net/rfc/attributes-on-constants
  . Added the pipe (|>) operator.
    RFC: https://wiki.php.net/rfc/pipe-operator-v3
  . Constructor property promotion can now be used for final properties.
    RFC: https://wiki.php.net/rfc/final_promotion
  . #[\Override] can now be applied to properties.
    RFC: https://wiki.php.net/rfc/override_properties
  . The #[\DelayedTargetValidation] attribute can be used to suppress
    compile-time errors from core (or extension) attributes that are used on
    invalid targets. These errors are instead reported at runtime if and when
    ReflectionAttribute::newInstance() is called.
    RFC: https://wiki.php.net/rfc/delayedtargetvalidation_attribute

- Curl:
  . Added support for share handles that are persisted across multiple PHP
    requests, safely allowing for more effective connection reuse.
    RFC: https://wiki.php.net/rfc/curl_share_persistence_improvement
  . Added support for CURLINFO_USED_PROXY (libcurl >= 8.7.0),
    CURLINFO_HTTPAUTH_USED, and CURLINFO_PROXYAUTH_USED
    (libcurl >= 8.12.0) to the curl_getinfo() function.
    When curl_getinfo() returns an array, the same information
    is available as "used_proxy", "httpauth_used", and "proxyauth_used"
    keys.
    CURLINFO_USED_PROXY gets zero set if no proxy was used in the
    previous transfer or a non-zero value if a proxy was used.
    CURLINFO_HTTPAUTH_USED and CURLINFO_PROXYAUTH_USED get bitmasks
    indicating the HTTP and proxy authentication methods that were
    used in the previous request. See CURLAUTH_* constants for
    possible values.
  . Added CURLOPT_INFILESIZE_LARGE Curl option, which is a safe
    replacement for CURLOPT_INFILESIZE. On certain systems,
    CURLOPT_INFILESIZE only accepts a 32-bit signed integer as the file
    size (2.0 GiB) even on 64-bit systems. CURLOPT_INFILESIZE_LARGE
    accepts the largest integer value the system can handle.
  . Added CURLFOLLOW_OBEYCODE, CURLFOLLOW_FIRSTONLY and CURLFOLLOW_ALL values for
    CURLOPT_FOLLOWLOCATION curl_easy_setopt option.
    CURLFOLLOW_OBEYCODE to follow more strictly in regard to redirect
    if they are allowed. CURLFOLLOW_FIRSTONLY to follow only the
    first redirect thus if there is any follow up redirect, it won't go
    any further. CURLFOLLOW_ALL is equivalent to setting CURLOPT_FOLLOWLOCATION
    to true.
  . Added support for CURLINFO_CONN_ID (libcurl >= 8.2.0) to the curl_getinfo()
    function. This constant allows retrieving the unique ID of the connection
    used by a cURL transfer. It is primarily useful when connection reuse or
    connection pooling logic is needed in PHP-level applications. When
    curl_getinfo() returns an array, this value is available as the "conn_id" key.
  . Added support for CURLINFO_QUEUE_TIME_T (libcurl >= 8.6.0) to the curl_getinfo()
    function. This constant allows retrieving the time (in microseconds) that the
    request spent in libcurl’s connection queue before it was sent.
    This value can also be retrieved by passing CURLINFO_QUEUE_TIME_T to the
    curl_getinfo() $option parameter.
  . Added support for CURLOPT_SSL_SIGNATURE_ALGORITHMS to specify the signature
    algorithms to use for TLS.

- DOM:
  . Added Dom\Element::$outerHTML.
  . Added $children property to Dom\ParentNode implementations.

- EXIF:
  . Add OffsetTime* Exif tags.
  . Added support for HEIF/HEIC.

- Filter:
  . Add new FILTER_THROW_ON_FAILURE flag which can be passed to the filter
    functions and will force an exception to be triggered when validation fails.
    The new flag cannot be combined with FILTER_NULL_ON_FAILURE; trying
    to do so will result in a ValueError being thrown.
    RFC: https://wiki.php.net/rfc/filter_throw_on_failure

- Intl:
  . Added class constants NumberFormatter::CURRENCY_ISO,
    NumberFormatter::CURRENCY_PLURAL, NumberFormatter::CASH_CURRENCY,
    and NumberFormatter::CURRENCY_STANDARD for various currency-related
    number formats.
  . Added Locale::addLikelySubtags and Locale::minimizeSubtags to
    handle likely tags on a given locale.
  . Added IntlListFormatter class to format, order, and punctuate
    a list of items with a given locale, IntlListFormatter::TYPE_AND,
    IntlListFormatter::TYPE_OR, IntlListFormatter::TYPE_UNITS operands and
    IntlListFormatter::WIDTH_WIDE, IntlListFormatter::WIDTH_SHORT and
    IntlListFormatter::WIDTH_NARROW widths.
    It is supported from icu 67.

- PDO_Sqlite:
  . Added class constant Pdo_Sqlite::ATTR_BUSY_STATEMENT.
  . Added class constants Pdo_Sqlite::ATTR_EXPLAIN_STATEMENT,
    Pdo_Sqlite::EXPLAIN_MODE_PREPARED, Pdo_Sqlite::EXPLAIN_MODE_EXPLAIN,
    Pdo_Sqlite::EXPLAIN_MODE_EXPLAIN_QUERY_PLAN.
  . Added PDO\Sqlite::ATTR_TRANSACTION_MODE connection attribute with
    possible values PDO\Sqlite::TRANSACTION_MODE_DEFERRED,
    PDO\Sqlite::TRANSACTION_MODE_IMMEDIATE,
    and PDO\Sqlite::TRANSACTION_MODE_EXCLUSIVE, allowing to configure
    the transaction mode to use when calling beginTransaction().

- Session:
  . session_set_cookie_params(), session_get_cookie_params(), and session_start()
    now support partitioned cookies via the "partitioned" key.
    RFC: https://wiki.php.net/rfc/CHIPS

- SOAP:
  . Enumeration cases are now dumped in __getTypes().
  . Implemented request #61105:
    support for Soap 1.2 Reason Text xml:lang attribute.
    The signature of SoapFault::__construct() and SoapServer::fault() therefore
    now have an optional $lang parameter.
    This support solves compatibility with .NET SOAP clients.

- Sqlite:
  . Added class constants Sqlite3Stmt::EXPLAIN_MODE_PREPARED,
    Sqlite3Stmt::EXPLAIN_MODE_EXPLAIN and
    Sqlite3Stmt::EXPLAIN_MODE_EXPLAIN_QUERY_PLAN.

- Standard:
  . mail() now returns the actual sendmail error and detects if the sendmail
    process was terminated unexpectedly. In such cases, a warning is emitted
    and the function returns false. Previously, these errors were silently
    ignored. This change affects only the sendmail transport.
  . getimagesize() now supports HEIF/HEIC images.
  . getimagesize() now supports SVG images when ext-libxml is also loaded.
    Similarly, image_type_to_extension() and image_type_to_mime_type()
    now also handle IMAGETYPE_SVG.
  . The array returned by getimagesize() now has two additional entries:
    "width_unit" and "height_unit" to indicate in which units the dimensions
    are expressed. These units are px by default. They are not necessarily
    the same (just to give one example: one may be cm and the other may be px).
  . setcookie() and setrawcookie() now support the "partitioned" key.
    RFC: https://wiki.php.net/rfc/CHIPS

- XSL:
  . The $namespace argument of XSLTProcessor::getParameter(),
    XSLTProcessor::setParameter() and XSLTProcessor::removeParameter()
    now actually works instead of being treated as empty.
    This only works if the $name argument does not use Clark notation
    and is not a QName because in those cases the namespace is taken
    from the namespace href or prefix respectively.

- Zlib:
  . flock() is now supported on zlib streams. Previously, this always
    failed to perform any locking action.

========================================
3. Changes in SAPI modules
========================================

- CLI:
  . Trying to set a process title that is too long with cli_set_process_title()
    will now fail instead of silently truncating the given title.
  . Added a new --ini=diff option to print INI settings changed from the builtin
    default.

- FPM:
  . FPM with httpd ProxyPass optionally decodes the full script path. Added
    fastcgi.script_path_encoded INI setting to prevent this new behavior.
  . FPM access log limit now respects log_limit value.

========================================
4. Deprecated Functionality
========================================

- Core:
  . Trying to produce output (e.g. with `echo`) within a user output handler
    is deprecated. The deprecation warning will bypass the handler producing the
    output to ensure it is visible; if there are nested output handlers the next
    one will still be used.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_4
  . Non-canonical cast names (boolean), (integer), (double), and (binary) have
    been deprecated, use (bool), (int), (float), and (string) respectively.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_non-standard_cast_names
  . The $exclude_disabled parameter of the get_defined_functions() function has
    been deprecated, as it no longer has any effect since PHP 8.0.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_the_exclude_disabled_parameter_of_get_defined_functions
  . Terminating case statements with a semicolon instead of a colon has
    been deprecated.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_semicolon_after_case_in_switch_statement
  . The backtick operator as an alias for shell_exec() has been deprecated.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_backticks_as_an_alias_for_shell_exec
  . Returning null from __debugInfo() has been deprecated.
    Return an empty array instead.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_debuginfo_returning_null
  . The report_memleaks INI directive has been deprecated.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_the_report_memleaks_ini_directive
  . Constant redeclaration has been deprecated.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_constant_redeclaration
  . Enacted the follow-up phase of the "Path to Saner Increment/Decrement
    operators" RFC, meaning that incrementing non-numeric strings is now
    deprecated. Instead the str_increment() function should be used.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#enact_follow-up_phase_of_the_path_to_saner_incrementdecrement_operators_rfc
  . The following closure binding issues, which already emit an E_WARNING, are
    now deprecated:
    - Binding an instance to a static closure
    - Binding methods to objects that are not instances of the class
      (or subclass) that the method is defined
    - Unbinding $this from a method
    - Unbinding $this from a closure that uses `$this`
    - Binding a closure to the scope of an internal class
    - Rebinding the scope of a closure created from a function or method
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_closure_binding_issues
  . Using null as an array offset or when calling array_key_exists() is now
    deprecated. Instead an empty string should be used.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_using_values_null_as_an_array_offset_and_when_calling_array_key_exists
  . Deriving $_SERVER['argc'] and $_SERVER['argv'] from the query string for non-CLI
    SAPIs has been deprecated. Configure register_argc_argv=0 and switch to either
    $_GET or $_SERVER['QUERY_STRING'] to access the information, after verifying
    that the usage is safe.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_the_register_argc_argv_ini_directive
  . The __sleep() and __wakeup() magic methods have been soft-deprecated. The
    __serialize() and __unserialize() magic methods should be used instead,
    or at the same time if compatibility with PHP 7 is required.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_the_sleep_and_wakeup_magic_methods
    RFC: https://wiki.php.net/rfc/soft-deprecate-sleep-wakeup

- Curl:
  . The curl_close() function has been deprecated, as CurlHandle objects are
    freed automatically.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_curl_close
  . The curl_share_close() function has been deprecated, as CurlShareHandle
    objects are freed automatically.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_curl_share_close

- Date:
  . The DATE_RFC7231 and DateTimeInterface::RFC7231 constants have been
    deprecated. This is because the associated timezone is ignored and always
    uses GMT.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_date_rfc7231_and_datetimeinterfacerfc7231
  . The __wakeup() magic method of DateTimeInterface, DateTime,
    DateTimeImmutable, DateTimeZone, DateInterval, and DatePeriod has been
    deprecated in favour of the __unserialize() magic method.
    Related to RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_the_sleep_and_wakeup_magic_methods

- FileInfo:
  . The finfo_close() function has been deprecated.
    As finfo objects are freed automatically.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_finfo_close
  . The $context parameter of the finfo_buffer() function has been deprecated
    as it is ignored.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_the_context_parameter_for_finfo_buffer

- GD:
  . The imagedestroy() function has been deprecated, as GdImage objects are
    freed automatically.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_imagedestroy

- Hash:
  . The MHASH_* constants have been deprecated.  These have been overlooked
    when the mhash*() function family has been deprecated per
    https://wiki.php.net/rfc/deprecations_php_8_1#mhash_function_family

- Intl:
  . The intl.error_level INI setting has been deprecated.
    Errors should either be checked manually or exceptions should be enabled
    by using the intl.use_exceptions INI setting.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_intlerror_level_ini_setting

- LDAP:
  - Specific Oracle Instant Client calls and constants have been deprecated.
    List of affected calls:
        ldap_connect() with wallet support
        ldap_connect_wallet()
    List of affected constants:
        GSLC_SSL_NO_UATH
        GSLC_SSL_ONEWAY_UATH
        GSLC_SSL_TWOWAY_UATH
    https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_building_ext_ldap_against_oracle_ldap

- MySQLi:
  . The mysqli_execute() alias function has been deprecated.
    Use mysqli_stmt_execute() instead.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#formally_deprecate_mysqli_execute

- OpenSSL:
  . The $key_length parameter for openssl_pkey_derive() has been deprecated.
    This is because it is either ignored, or truncates the key, which can be
    a vulnerability.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_key_length_parameter_of_openssl_pkey_derive

- PDO:
  . The "uri:" DSN scheme has been deprecated due to security concerns with
    DSNs coming from remote URIs.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_pdo_s_urischeme
  . Driver specific constants in the PDO class have been deprecated.
    List of affected constants and their replacement:
        PDO::DBLIB_ATTR_CONNECTION_TIMEOUT => Pdo\Dblib::ATTR_CONNECTION_TIMEOUT
        PDO::DBLIB_ATTR_QUERY_TIMEOUT => Pdo\Dblib::ATTR_QUERY_TIMEOUT
        PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER => Pdo\Dblib::ATTR_STRINGIFY_UNIQUEIDENTIFIER
        PDO::DBLIB_ATTR_VERSION => Pdo\Dblib::ATTR_VERSION
        PDO::DBLIB_ATTR_TDS_VERSION => Pdo\Dblib::ATTR_TDS_VERSION
        PDO::DBLIB_ATTR_SKIP_EMPTY_ROWSETS => Pdo\Dblib::ATTR_SKIP_EMPTY_ROWSETS
        PDO::DBLIB_ATTR_DATETIME_CONVERT => Pdo\Dblib::ATTR_DATETIME_CONVERT
        PDO::FB_ATTR_DATE_FORMAT => Pdo\Firebird::ATTR_DATE_FORMAT
        PDO::FB_ATTR_TIME_FORMAT => Pdo\Firebird::ATTR_TIME_FORMAT
        PDO::FB_ATTR_TIMESTAMP_FORMAT => Pdo\Firebird::ATTR_TIMESTAMP_FORMAT
        PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => Pdo\Mysql::ATTR_USE_BUFFERED_QUERY
        PDO::MYSQL_ATTR_LOCAL_INFILE => Pdo\Mysql::ATTR_LOCAL_INFILE
        PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY => Pdo\Mysql::ATTR_LOCAL_INFILE_DIRECTORY
        PDO::MYSQL_ATTR_INIT_COMMAND => Pdo\Mysql::ATTR_INIT_COMMAND
        PDO::MYSQL_ATTR_MAX_BUFFER_SIZE => Pdo\Mysql::ATTR_MAX_BUFFER_SIZE
        PDO::MYSQL_ATTR_READ_DEFAULT_FILE => Pdo\Mysql::ATTR_READ_DEFAULT_FILE
        PDO::MYSQL_ATTR_READ_DEFAULT_GROUP => Pdo\Mysql::ATTR_READ_DEFAULT_GROUP
        PDO::MYSQL_ATTR_COMPRESS => Pdo\Mysql::ATTR_COMPRESS
        PDO::MYSQL_ATTR_DIRECT_QUERY => Pdo\Mysql::ATTR_DIRECT_QUERY
        PDO::MYSQL_ATTR_FOUND_ROWS => Pdo\Mysql::ATTR_FOUND_ROWS
        PDO::MYSQL_ATTR_IGNORE_SPACE => Pdo\Mysql::ATTR_IGNORE_SPACE
        PDO::MYSQL_ATTR_SSL_KEY => Pdo\Mysql::ATTR_SSL_KEY
        PDO::MYSQL_ATTR_SSL_CERT => Pdo\Mysql::ATTR_SSL_CERT
        PDO::MYSQL_ATTR_SSL_CA => Pdo\Mysql::ATTR_SSL_CA
        PDO::MYSQL_ATTR_SSL_CAPATH => Pdo\Mysql::ATTR_SSL_CAPATH
        PDO::MYSQL_ATTR_SSL_CIPHER => Pdo\Mysql::ATTR_SSL_CIPHER
        PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => Pdo\Mysql::ATTR_SSL_VERIFY_SERVER_CERT
        PDO::MYSQL_ATTR_SERVER_PUBLIC_KEY => Pdo\Mysql::ATTR_SERVER_PUBLIC_KEY
        PDO::MYSQL_ATTR_MULTI_STATEMENTS => Pdo\Mysql::ATTR_MULTI_STATEMENTS
        PDO::ODBC_ATTR_USE_CURSOR_LIBRARY => Pdo\Odbc::ATTR_USE_CURSOR_LIBRARY
        PDO::ODBC_ATTR_ASSUME_UTF8 => Pdo\Odbc::ATTR_ASSUME_UTF8
        PDO::ODBC_SQL_USE_IF_NEEDED => Pdo\Odbc::SQL_USE_IF_NEEDED
        PDO::ODBC_SQL_USE_DRIVER => Pdo\Odbc::SQL_USE_DRIVER
        PDO::ODBC_SQL_USE_ODBC => Pdo\Odbc::SQL_USE_ODBC
        PDO::PGSQL_ATTR_DISABLE_PREPARES => Pdo\Pgsql::ATTR_DISABLE_PREPARES
        PDO::SQLITE_ATTR_EXTENDED_RESULT_CODES => Pdo\Sqlite::ATTR_EXTENDED_RESULT_CODES
        PDO::SQLITE_ATTR_OPEN_FLAGS => Pdo\Sqlite::OPEN_FLAGS
        PDO::SQLITE_ATTR_READONLY_STATEMENT => Pdo\Sqlite::ATTR_READONLY_STATEMENT
        PDO::SQLITE_DETERMINISTIC => Pdo\Sqlite::DETERMINISTIC
        PDO::SQLITE_OPEN_READONLY => Pdo\Sqlite::OPEN_READONLY
        PDO::SQLITE_OPEN_READWRITE => Pdo\Sqlite::OPEN_READWRITE
        PDO::SQLITE_OPEN_CREATE => Pdo\Sqlite::OPEN_CREATE
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_driver_specific_pdo_constants_and_methods
  . Driver specific methods in the PDO class have been deprecated.
    List of affected methods and their replacement:
        PDO::pgsqlCopyFromArray() => Pdo\Pgsql::copyFromArray()
        PDO::pgsqlCopyFromFile() => Pdo\Pgsql::copyFromFile()
        PDO::pgsqlCopyToArray() => Pdo\Pgsql::copyToArray()
        PDO::pgsqlCopyToFile() => Pdo\Pgsql::copyToFile()
        PDO::pgsqlGetNotify() => Pdo\Pgsql::getNotify()
        PDO::pgsqlGetPid() => Pdo\Pgsql::getPid()
        PDO::pgsqlLOBCreate() => Pdo\Pgsql::lobCreate()
        PDO::pgsqlLOBOpen() => Pdo\Pgsql::lobOpen()
        PDO::pgsqlLOBUnlink() => Pdo\Pgsql::lobUnlink()
        PDO::sqliteCreateAggregate() => Pdo\Sqlite::createAggregate()
        PDO::sqliteCreateCollation() => Pdo\Sqlite::createCollation()
        PDO::sqliteCreateFunction() => Pdo\Sqlite::createFunction()
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_driver_specific_pdo_constants_and_methods

- PDO_PGSQL: Constants related to transaction states have been deprecated:
        PDO::PGSQL_TRANSACTION_IDLE, PDO::PGSQL_TRANSACTION_ACTIVE, PDO::PGSQL_TRANSACTION_INTRANS,
        PDO::PGSQL_TRANSACTION_INERROR, PDO::PGSQL_TRANSACTION_UNKNOWN.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#extpdo_deprecations

- Reflection:
  . The setAccessible() methods of various Reflection objects have been
    deprecated, as those no longer have an effect.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_reflectionsetaccessible
  . Calling ReflectionClass::getConstant() for constants that do not exist has
    been deprecated.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_reflectionclassgetconstant_for_missing_constants
  . Calling ReflectionProperty::getDefaultValue() for properties without default
    values has been deprecated.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_reflectionpropertygetdefaultvalue_for_properties_without_default_values

- SPL:
  . Unregistering all autoloaders by passing the spl_autoload_call() function
    as a callback argument to spl_autoload_unregister() has been deprecated.
    Instead if this is needed, one should iterate over the return value of
    spl_autoload_functions() and call spl_autoload_unregister() on each value.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_passing_spl_autoload_call_to_spl_autoload_unregister
  . The SplObjectStorage::contains(), SplObjectStorage::attach(), and
    SplObjectStorage::detach() methods have been deprecated in favour of
    SplObjectStorage::offsetExists(), SplObjectStorage::offsetSet(), and
    SplObjectStorage::offsetUnset() respectively.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_splobjectstoragecontains_splobjectstorageattach_and_splobjectstoragedetach
  . Using ArrayObject and ArrayIterator with objects has been deprecated.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_arrayobject_and_arrayiterator_with_objects

- Standard:
  . The socket_set_timeout() alias function has been deprecated.
    Use stream_set_timeout() instead.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#formally_deprecate_socket_set_timeout
  . Passing null to to readdir(), rewinddir(), and closedir() to use the last
    opened directory has been deprecated. Provide the last opened directory
    explicitly instead.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_passing_null_to_readdir_rewinddir_and_closedir
  . Passing integers outside the interval [0, 255] to chr() is now deprecated.
    This is because a byte can only hold a value within this interval.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_passing_integers_outside_the_interval_0_255_to_chr
  . Passing a string which is not a single byte to ord() is now deprecated,
    this is indicative of a bug.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_passing_string_which_are_not_one_byte_long_to_ord
  . The locally predefined variable $http_response_header is deprecated.
    Instead one should call the http_get_last_response_headers() function.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_the_http_response_header_predefined_variable

- XML:
  . The xml_parser_free() function has been deprecated, as XMLParser objects
    are freed automatically.
    RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_xml_parser_free

========================================
5. Changed Functions
========================================

- Intl:
  . IntlDateFormatter::setTimeZone()/datefmt_set_timezone()
    throws an IntlException on uninitialised classes/clone failures.
  . grapheme_extract() properly assigns $next value when skipping over
    invalid starting bytes. Previously there were cases where it would
    point to the start of the grapheme boundary instead of the end.
  . Locale:: methods throw a ValueError when locale inputs contain null
    bytes.
  . transliterator_get_error_code(), transliterator_get_error_message()
    TransLiterator::getErrorCode(), and TransLiterator::getErrorMessage()
    have dropped the false from the return type union. Returning false
    was actually never possible.
  . grapheme_strpos(), grapheme_stripos(), grapheme_strrpos(),
    grapheme_strripos(), grapheme_substr(), grapheme_strstr()
    and grapheme_stristr() functions add $locale parameter.
    RFC: https://wiki.php.net/rfc/grapheme_add_locale_for_case_insensitive

- LDAP:
  . ldap_get_option() now accepts a NULL connection, like ldap_set_option(),
    to allow retrieval of global options.

- libxml:
  . libxml_set_external_entity_loader() now has a formal return type of true.

- OpenSSL:
  . openssl_public_encrypt() and openssl_private_decrypt() have a new parameter
    $digest_algo that allows specifying the hash digest algorithm for OAEP padding.
  . openssl_sign() and openssl_verify() have a new parameter $padding to allow
    using more secure RSA PSS padding.
  . openssl_cms_encrypt() $cipher_algo parameter can be a string with the
    cipher name. That allows to use more algorithms including AES GCM cipher
    algorithms for auth enveloped data.

- PCNTL:
  . pcntl_exec() now has a formal return type of false.
  . pcntl_waitid() takes an additional resource_usage argument to
    gather various platform specific metrics about the child process.

- PDO_PGSQL:
  . PDO::pgsqlCopyFromArray now supports Iterable inputs.
  . Pdo\Pgsql::setAttribute and Pdo\Pgsql::prepare support setting
    PDO::ATTR_PREFETCH to 0 which enters lazy fetch mode.
    In this mode, statements cannot be run in parallel.

- PDO_SQLITE:
  . SQLite PDO::quote() will now throw an exception or emit a warning,
    depending on the error mode, if the string contains a null byte.
  . PDO::sqliteCreateCollation will now throw an exception
    if the callback has the wrong return type, making it more
    in line with Pdo_Sqlite::createCollation behavior.

- PGSQL:
  . pg_copy_from now supports Iterable inputs.
  . pg_connect checks if the connection_string argument contains
    any null byte.
  . pg_close_stmt checks if the statement_name argument contains
    any null byte.

- POSIX:
  . posix_ttyname sets last_error to EBADF when encountering
    an invalid file descriptor.
  . posix_isatty raises an E_WARNING message when encountering
    an invalid file descriptor.
  . posix_fpathconf checks invalid file descriptors and sets
    last_error to EBADF and raises an E_WARNING message.
  . posix_kill throws a ValueError when the process_id argument is lower
    or greater than what the platform supports (signed integer or long
    range), posix_setpgid throws a ValueError when the process_id or
    the process_group_id is lower than zero or greater than
    what the platform supports.
  . posix_setrlimit throws a ValueError when the hard_limit or soft_limit
    arguments are lower than -1 or if soft_limit is greater than hard_limit.

- Reflection:
  . The output of ReflectionClass::__toString() for enums has changed to
    better indicate that the class is an enum, and that the enum cases
    are enum cases rather than normal class constants.
  . The output of ReflectionProperty::__toString() for properties with
    hooks has changed to indicate what hooks the property has, whether those
    hooks are final, and whether the property is virtual. This also affects
    the output of ReflectionClass::__toString() when a class contains hooked
    properties.
  . ReflectionAttribute::newInstance() can now throw errors for internal
    attributes if the attribute was applied on an invalid target and the
    error was delayed from compile time to runtime via the
    #[\DelayedTargetValidation] attribute.
    RFC: https://wiki.php.net/rfc/delayedtargetvalidation_attribute

- Session:
  . session_start is stricter in regard to the options argument.
    It throws a ValueError if the array is not a hashmap, or
    a TypeError if the read_and_close value is not a valid type
    compatible with int.

- SNMP:
  . snmpget, snmpset, snmp_get2, snmp_set2, snmp_get3, snmp_set3
    and SNMP::__construct() throw a ValueError when the hostname
    is too large, contains any null byte or if the port is given
    when negative or greater than 65535, timeout and retries values
    are lower than -1 or too large.

- Sockets:
  . socket_create_listen, socket_bind and socket_sendto throw a
    ValueError if the port is lower than 0 or greater than 65535,
    and also if any of the hints array entries are indexed numerically.
  . socket_addrinfo_lookup throws a TypeError if any of the hints
    values cannot be cast to int and can throw a ValueError if
    any of these values overflow.
  . socket_set_option with MCAST_LEAVE_GROUP/MCAST_LEAVE_SOURCE_GROUP
    options will throw an exception if the value isn't a valid object
    or array.
  . socket_create/socket_bind can create AF_PACKET family sockets.
  . socket_getsockname gets the interface index and its string
    representation with AF_PACKET socket.
  . socket_set_option with multicast context throws a ValueError
    when the created socket is not of AF_INET/AF_INET6 family.

- Tidy:
  . tidy::__construct/parseFile/parseString now throws a ValueError if the
    configuration contains an invalid value or attempts to set a read-only
    internal entry, and a TypeError if a configuration key is not a string.

- Zlib:
  . The "use_include_path" argument for the
    gzfile, gzopen and readgzfile functions has been changed
    from int to boolean.
  . gzfile, gzopen and readgzfile functions now respect the default
    stream context.

========================================
6. New Functions
========================================

- Core:
  . get_error_handler() allows retrieving the current user-defined error handler
    function.
    RFC: https://wiki.php.net/rfc/get-error-exception-handler
  . get_exception_handler() allows retrieving the current user-defined exception
    handler function.
    RFC: https://wiki.php.net/rfc/get-error-exception-handler
  . The clone language construct is now a function and supports reassigning
    (readonly) properties during cloning via the new $withProperties parameter.
    RFC: https://wiki.php.net/rfc/clone_with_v2
  . Added Closure::getCurrent() to receive currently executing closure.

- Curl:
  . curl_multi_get_handles() allows retrieving all CurlHandles currently
    attached to a CurlMultiHandle. This includes both handles added using
    curl_multi_add_handle() and handles accepted by CURLMOPT_PUSHFUNCTION.
  . curl_share_init_persistent() allows creating a share handle that is
    persisted across multiple PHP requests.
    RFC: https://wiki.php.net/rfc/curl_share_persistence_improvement

- DOM:
  . Added Dom\Element::getElementsByClassName().
  . Added Dom\Element::insertAdjacentHTML().

- Enchant:
  . Added enchant_dict_remove_from_session() to remove a word added to the
    spellcheck session via enchant_dict_add_to_session().
  . Added enchant_dict_remove() to put a word on the exclusion list and
    remove it from the session dictionary.

- Intl:
  . Added locale_is_right_to_left/Locale::isRightToLeft, returns true if
    the locale is written right to left (after its enrichment with likely subtags).
  . Added grapheme_levenshtein() function.
    RFC: https://wiki.php.net/rfc/grapheme_levenshtein

- Opcache:
  . Added opcache_is_script_cached_in_file_cache().

- Pdo\Sqlite:
  . Added support for Pdo\Sqlite::setAuthorizer(), which is the equivalent of
    SQLite3::setAuthorizer(). The only interface difference is that the
    pdo version returns void.

- PGSQL:
  . pg_close_stmt offers an alternative way to close a prepared
    statement from the DEALLOCATE sql command in that we can reuse
    its name afterwards.
  . pg_service returns the ongoing service name of the connection.

- Reflection:
  . ReflectionConstant::getFileName() was introduced.
  . ReflectionConstant::getExtension() and
    ReflectionConstant::getExtensionName() were introduced.
  . ReflectionConstant::getAttributes() was introduced.
    RFC: https://wiki.php.net/rfc/attributes-on-constants
  . ReflectionProperty::getMangledName() was introduced.

- Sqlite:
  . Sqlite3Stmt::busy to check if a statement had been fetched
    but not completely.

- Standard:
  . Added array_first() and array_last().
    RFC: https://wiki.php.net/rfc/array_first_last

========================================
7. New Classes and Interfaces
========================================

- Core:
  . NoDiscard attribute was added.
    RFC: https://wiki.php.net/rfc/marking_return_value_as_important
  . DelayedTargetValidation attribute was added.
    RFC: https://wiki.php.net/rfc/delayedtargetvalidation_attribute

- Curl:
  . CurlSharePersistentHandle representing a share handle that is persisted
    across multiple PHP requests.
    RFC: https://wiki.php.net/rfc/curl_share_persistence_improvement

- Filter:
  . Filter\FilterException and Filter\FilterFailedException for use
    when FILTER_THROW_ON_FAILURE has been enabled.
    RFC: https://wiki.php.net/rfc/filter_throw_on_failure

- URI:
  . Uri\UriException, Uri\InvalidUriException, Uri\UriComparisonMode,
    Uri\Rfc3986\Uri, Uri\WhatWg\InvalidUrlException,
    Uri\WhatWg\UrlValidationErrorType, Uri\WhatWg\UrlValidationError,
    and Uri\WhatWg\Url are added.
    RFC: https://wiki.php.net/rfc/url_parsing_api

========================================
8. Removed Extensions and SAPIs
========================================

========================================
9. Other Changes to Extensions
========================================

- Curl:
  . curl_easy_setopt with CURLOPT_FOLLOWLOCATION option's value no longer
    is treated as boolean but integer to handle CURLFOLLOW_OBEYCODE and
    CURLFOLLOW_FIRSTONLY.

- Fileinfo:
  . Upgraded file from 5.45 to 5.46.
  . The return type of finfo_close() has been changed to true, rather
    than bool.

- Intl:
  . Intl's internal error mechanism has been modernized so that it
    indicates more accurately which call site caused what error.
    Moreover, some ext/date exceptions have been wrapped inside a
    IntlException now.

- Lexbor:
  . An always enabled lexbor extension is added. It contains the lexbor
    library that was separated from ext/dom for being reused among other
    extensions. The new extension is not directly exposed to userland.

- Opcache:
  . The Opcache extension is now always built into the PHP binary and is always
    loaded. The INI directives opcache.enable and opcache.enable_cli are still
    honored.

- URI:
  . An always enabled uri extension is added that can be used for handling
    URIs and URLs according to RFC 3986 and WHATWG URL.
    RFC: https://wiki.php.net/rfc/url_parsing_api

- PDO_Sqlite:
  . Increased minimum release version support from 3.7.7 to 3.7.17.

- Readline:
  . The return types of readline_add_history(), readline_clear_history(), and
    readline_callback_handler_install() have been changed to true, rather
    than bool.

- Reflection:
  . ReflectionConstant is no longer final.

========================================
10. New Global Constants
========================================

- Core:
  . PHP_BUILD_DATE.
  . PHP_BUILD_PROVIDER.

- Curl:
  . CURLINFO_USED_PROXY.
  . CURLINFO_HTTPAUTH_USED.
  . CURLINFO_PROXYAUTH_USED.
  . CURLINFO_CONN_ID.
  . CURLINFO_QUEUE_TIME_T.
  . CURLOPT_INFILESIZE_LARGE.
  . CURLFOLLOW_ALL.
  . CURLFOLLOW_OBEYCODE.
  . CURLFOLLOW_FIRSTONLY.

- Filter:
  . FILTER_THROW_ON_FAILURE.

- Intl:
  . DECIMAL_COMPACT_SHORT.
  . DECIMAL_COMPACT_LONG.

- OpenSSL:
  . OPENSSL_PKCS1_PSS_PADDING.
  . PKCS7_NOSMIMECAP.
  . PKCS7_CRLFEOL.
  . PKCS7_NOCRL.
  . PKCS7_NO_DUAL_CONTENT.

- POSIX:
  . POSIX_SC_OPEN_MAX.

- Sockets:
  . IPPROTO_ICMP/IPPROTO_ICMPV6.
  . TCP_FUNCTION_BLK (FreeBSD only).
  . TCP_FUNCTION_ALIAS (FreeBSD only).
  . TCP_REUSPORT_LB_NUMA (FreeBSD only).
  . TCP_REUSPORT_LB_NUMA_NODOM (FreeBSD only).
  . TCP_REUSPORT_LB_NUMA_CURDOM (FreeBSD only).
  . TCP_BBR_ALGORITHM (FreeBSD only).
  . AF_PACKET (Linux only).
  . ETH_P_IP (Linux only).
  . ETH_P_IPV6 (Linux only).
  . ETH_P_LOOP (Linux only).
  . ETH_P_ALL (Linux only).
  . IP_BINDANY (FreeBSD/NetBSD/OpenBSD only).
  . SO_BUSY_POLL (Linux only).
  . UDP_SEGMENT (Linux only).
  . SHUT_RD.
  . SHUT_WR.
  . SHUT_RDWR.

- Tokenizer:
  . T_VOID_CAST.
  . T_PIPE.

- Standard:
  . IMAGETYPE_SVG when libxml is loaded.

========================================
11. Changes to INI File Handling
========================================

- Core:
  . Added fatal_error_backtraces to control whether fatal errors should include
    a backtrace.
    RFC: https://wiki.php.net/rfc/error_backtraces_v2
  . Added startup-only max_memory_limit INI setting to control the maximum
    memory_limit that may be configured at startup or runtime. Exceeding this
    value emits a warning, unless set to -1, and sets memory_limit to the
    current max_memory_limit instead.
    ML discussion: https://externals.io/message/127108

- Opcache:
  . Added opcache.file_cache_read_only to support a read-only
    opcache.file_cache directory, for use with read-only file systems
    (e.g. read-only Docker containers).
    Best used with opcache.validate_timestamps=0,
    opcache.enable_file_override=1,
    and opcache.file_cache_consistency_checks=0.
    Note: A cache generated with a different build of PHP, a different file
    path, or different settings (including which extensions are loaded), may be
    ignored.
  . The default value of opcache.jit_hot_loop is now 61 (a prime) to prevent it
    from being a multiple of loop iteration counts.
    It is recommended that this parameter is set to a prime number.
  . Changing opcache.memory_consumption when OPcache SHM is already set up
    will now correctly report a failure instead of silently doing nothing and
    showing misleading values in PHPInfo.

- OpenSSL:
  . Added openssl.libctx to select the OpenSSL library context type. Either
    custom libctx for each thread can be used or a single global (default)
    libctx is used.

========================================
12. Windows Support
========================================

* The configuration variables PHP_VERSION, PHP_MINOR_VERSION, and
  PHP_RELEASE_VERSION are now always numbers.  Previously, they have been
  strings for buildconf builds.

* phpize builds now reflect the source tree in the build dir (as it already
  worked for in-tree builds); some extension builds (especially when using
  Makefile.frag.w32) may need adjustments.

* --enable-sanitizer is now supported for MSVC builds.  This enables ASan and
  debug assertions, and is supported as of MSVC 16.10 and Windows 10.

* The --with-uncritical-warn-choke configuration option for clang builds is
  no longer supported.  Select warnings to suppress via CFLAGS instead.

* COM:
  . The extension is now build shared by default; previously it defaulted to a
    static extension, although the official Windows binaries built a shared
    extension.

* FFI:
  . It is no longer necessary to specify the library when using FFI::cdef()
    and FFI::load(). However, this convenience feature should not be used in
    production.

* Streams:
  . If only pipe streams are contained in the $read array, and the $write and
    $except arrays are empty, stream_select() now behaves similar to POSIX
    systems, i.e. the function only returns if at least one pipe is ready to be
    read, or after the timeout expires.  Previously, stream_select() returned
    immediately, reporting all streams as ready to read.

========================================
13. Other Changes
========================================

- Core:
  . The high resolution timer (`hrtime()`) on macOS now uses the recommended
    `clock_gettime_nsec_np(CLOCK_UPTIME_RAW)` API instead of
    `mach_absolute_time()`.

- CLI/CGI:
  . The `-z` or `--zend-extension` option has been removed as it was
    non-functional. Use `-d zend_extension=<path>` instead.

- PDO_ODBC
  . The fetch behaviour for larger columns has been changed. Rather than
    fetching 256 byte blocks, PDO_ODBC will try to fetch a larger block size;
    currently, this is the page size minus string overhead. Drivers that
    return SQL_NO_TOTAL in SQLGetData are also better handled as well.
    This should improve compatibility and performance. See GH-10809, GH-10733.

========================================
14. Performance Improvements
========================================

- Core:
  . Remove OPcodes for identity comparisons against booleans, particularly
    for the match(true) pattern.
  . Add OPcode specialization for `=== []` and `!== []` comparisons.
  . Creating exception objects is now much faster.
  . The parts of the code that used SSE2 have been adapted to use SIMD
    with ARM NEON as well.
  . Introduced the TAILCALL VM, enabled by default when compiling with Clang>=19
    on x86_64 or aarch64. The TAILCALL VM is as fast as the HYBRID VM used when
    compiling with GCC. This makes PHP binaries built with Clang>=19 as fast as
    binaries built with GCC. The performance of the CALL VM, used with other
    compilers, has also improved considerably.

- Intl:
  . Now avoids creating extra string copies when converting strings
    for use in the collator.

- MBString:
  . The parts of the code that used SSE2 have been adapted to use SIMD
    with ARM NEON as well.

- Opcache:
  . Improved performance of fetching TLS variables in JIT'ed code in non-Glibc
    builds.

- ReflectionProperty:
  . Improved performance of the following methods: getValue(), getRawValue(),
    isInitialized(), setValue(), setRawValue().

- SPL:
  . Improved performance of dimension accessors and methods of SplFixedArray.

- Standard:
  . Improved performance of array functions with callbacks
    (array_find, array_filter, array_map, usort, ...).
  . Improved performance of urlencode() and rawurlencode().
  . Improved unpack() performance with nameless repetitions by avoiding
    creating temporary strings and reparsing them.
  . Improved pack() performance.
  . Minor improvements in array_chunk() performance.

- XMLReader:
  . Improved property access performance.

- XMLWriter:
  . Improved performance and reduced memory consumption.
