From 4d036b34a5e59e5821c15fb26859dee7492cd35c Mon Sep 17 00:00:00 2001 From: Jordi Kroon Date: Mon, 28 Sep 2026 20:53:29 +0200 Subject: [PATCH 01/17] Added initial files for 8.6 migration --- appendices/migration86.xml | 56 ++++++++++++++++++++++ appendices/migration86/constants.xml | 25 ++++++++++ appendices/migration86/deprecated.xml | 25 ++++++++++ appendices/migration86/incompatible.xml | 25 ++++++++++ appendices/migration86/new-classes.xml | 25 ++++++++++ appendices/migration86/new-features.xml | 25 ++++++++++ appendices/migration86/new-functions.xml | 25 ++++++++++ appendices/migration86/other-changes.xml | 25 ++++++++++ appendices/migration86/windows-support.xml | 25 ++++++++++ manual.xml | 1 + 10 files changed, 257 insertions(+) create mode 100644 appendices/migration86.xml create mode 100644 appendices/migration86/constants.xml create mode 100644 appendices/migration86/deprecated.xml create mode 100644 appendices/migration86/incompatible.xml create mode 100644 appendices/migration86/new-classes.xml create mode 100644 appendices/migration86/new-features.xml create mode 100644 appendices/migration86/new-functions.xml create mode 100644 appendices/migration86/other-changes.xml create mode 100644 appendices/migration86/windows-support.xml diff --git a/appendices/migration86.xml b/appendices/migration86.xml new file mode 100644 index 000000000000..89cdef36774f --- /dev/null +++ b/appendices/migration86.xml @@ -0,0 +1,56 @@ + + + Migrating from PHP 8.5.x to PHP 8.6.x + + + This new minor version brings with it a number of + new features and a + few incompatibilities + that should be tested for before switching PHP versions in production + environments. + + + + &manual.migration.seealso; + 7.1.x, + 7.2.x, + 7.3.x, + 7.4.x, + 8.0.x, + 8.1.x, + 8.2.x, + 8.3.x, + 8.4.x, + 8.5.x. + + + &appendices.migration86.new-features; + &appendices.migration86.new-classes; + &appendices.migration86.new-functions; + &appendices.migration86.constants; + &appendices.migration86.incompatible; + &appendices.migration86.deprecated; + &appendices.migration86.other-changes; + &appendices.migration86.windows-support; + + + diff --git a/appendices/migration86/constants.xml b/appendices/migration86/constants.xml new file mode 100644 index 000000000000..1886d0a6ba4e --- /dev/null +++ b/appendices/migration86/constants.xml @@ -0,0 +1,25 @@ + + + New Global Constants + + + diff --git a/appendices/migration86/deprecated.xml b/appendices/migration86/deprecated.xml new file mode 100644 index 000000000000..cfdce69aca1e --- /dev/null +++ b/appendices/migration86/deprecated.xml @@ -0,0 +1,25 @@ + + + Deprecated Features + + + diff --git a/appendices/migration86/incompatible.xml b/appendices/migration86/incompatible.xml new file mode 100644 index 000000000000..432ff047b489 --- /dev/null +++ b/appendices/migration86/incompatible.xml @@ -0,0 +1,25 @@ + + + Backward Incompatible Changes + + + diff --git a/appendices/migration86/new-classes.xml b/appendices/migration86/new-classes.xml new file mode 100644 index 000000000000..d44d2decb661 --- /dev/null +++ b/appendices/migration86/new-classes.xml @@ -0,0 +1,25 @@ + + + New Classes and Interfaces + + + diff --git a/appendices/migration86/new-features.xml b/appendices/migration86/new-features.xml new file mode 100644 index 000000000000..6b95f21881b6 --- /dev/null +++ b/appendices/migration86/new-features.xml @@ -0,0 +1,25 @@ + + + New Features + + + diff --git a/appendices/migration86/new-functions.xml b/appendices/migration86/new-functions.xml new file mode 100644 index 000000000000..6947ecfa0ede --- /dev/null +++ b/appendices/migration86/new-functions.xml @@ -0,0 +1,25 @@ + + + New Functions + + + diff --git a/appendices/migration86/other-changes.xml b/appendices/migration86/other-changes.xml new file mode 100644 index 000000000000..42be132a941a --- /dev/null +++ b/appendices/migration86/other-changes.xml @@ -0,0 +1,25 @@ + + + Other Changes + + + diff --git a/appendices/migration86/windows-support.xml b/appendices/migration86/windows-support.xml new file mode 100644 index 000000000000..e4e911aa539e --- /dev/null +++ b/appendices/migration86/windows-support.xml @@ -0,0 +1,25 @@ + + + Windows Support + + + diff --git a/manual.xml b/manual.xml index f393b9f67120..d9302073d28d 100644 --- a/manual.xml +++ b/manual.xml @@ -412,6 +412,7 @@ &Appendices; &appendices.history; &appendices.examples; + &appendices.migration86; &appendices.migration85; &appendices.migration84; &appendices.migration83; From 81885f1429203fdf79a65999b11884dcc1d44bf1 Mon Sep 17 00:00:00 2001 From: Jordi Kroon Date: Mon, 28 Sep 2026 21:18:50 +0200 Subject: [PATCH 02/17] Document new classes & functions --- appendices/migration86/new-classes.xml | 81 +++++++++ appendices/migration86/new-functions.xml | 222 +++++++++++++++++++++++ 2 files changed, 303 insertions(+) diff --git a/appendices/migration86/new-classes.xml b/appendices/migration86/new-classes.xml index d44d2decb661..ad3dbbd7f7c3 100644 --- a/appendices/migration86/new-classes.xml +++ b/appendices/migration86/new-classes.xml @@ -2,6 +2,87 @@ New Classes and Interfaces + + Core + + SortDirection + StreamError + StreamException + StreamErrorStore + StreamErrorMode + StreamErrorCode + Io\IoException + Io\Poll\Context + Io\Poll\Watcher + Io\Poll\Backend + Io\Poll\Event + Io\Poll\Handle + Io\Poll\PollException + Io\Poll\FailedPollOperationException + Io\Poll\FailedContextInitializationException + Io\Poll\FailedHandleAddException + Io\Poll\FailedWatcherModificationException + Io\Poll\FailedPollWaitException + Io\Poll\BackendUnavailableException + Io\Poll\InactiveWatcherException + Io\Poll\HandleAlreadyWatchedException + Io\Poll\InvalidHandleException + StreamPollHandle + + + + + + + + Date + + Time\Duration + Time\TimeException + + + + + + Intl + + IntlNumberRangeFormatter + + + + + OpenSSL + + Openssl\OpensslException + Openssl\Session + Openssl\Psk + + + + + + SNMP + + Snmp\Mib + Snmp\OidOutput + Snmp\Output + Snmp\StringOutput + + + + + + + URI + + Uri\Rfc3986\UriBuilder + Uri\WhatWg\UrlBuilder + Uri\WhatWg\UrlPercentEncodingMode + + + + + + + clamp returns the given value if in range, else + returns the nearest bound. + + + stream_last_errors + stream_clear_errors + stream_socket_get_crypto_status + + + + + GMP + + + gmp_powm_sec + gmp_prevprime + + + + + Intl + + + + grapheme_strrev + + IntlDatePatternGenerator::getSkeleton + + + IntlDatePatternGenerator::getBaseSkeleton + + + + Locale::getDisplayKeyword + + locale_get_display_keyword + + Locale::getDisplayKeywordValue + + locale_get_display_keyword_value + + SpoofChecker::areBidiConfusable + + + SpoofChecker::getBidiSkeleton + + + SpoofChecker::getSkeleton + + + + + + MySQLi + + + + + mysqli::quote_string + + mysqli_quote_string + + + + + Reflection + + + + ReflectionAttribute::inNamespace + + + ReflectionAttribute::getNamespaceName + + + ReflectionAttribute::getShortName + + + ReflectionConstant::inNamespace + + + + ReflectionParameter::getDocComment + + + + ReflectionProperty::isReadable + + + ReflectionProperty::isWritable + + + + + + SNMP + + + + snmp_init_mib + snmp_set_mib_option + snmp_set_output_option + snmp_set_string_output_format + + SNMP::setOidOutputFormat + + + SNMP::setStringOutputFormat + + + + + + Sodium + + + sodium_crypto_ipcrypt_keygen + sodium_crypto_ipcrypt_encrypt + sodium_crypto_ipcrypt_decrypt + sodium_crypto_ipcrypt_nd_keygen + sodium_crypto_ipcrypt_nd_encrypt + sodium_crypto_ipcrypt_nd_decrypt + sodium_crypto_ipcrypt_ndx_keygen + sodium_crypto_ipcrypt_ndx_encrypt + sodium_crypto_ipcrypt_ndx_decrypt + sodium_crypto_ipcrypt_pfx_keygen + sodium_crypto_ipcrypt_pfx_encrypt + sodium_crypto_ipcrypt_pfx_decrypt + sodium_bin2ip + sodium_ip2bin + sodium_crypto_xof_shake128 + sodium_crypto_xof_shake128_init + sodium_crypto_xof_shake128_update + sodium_crypto_xof_shake128_squeeze + sodium_crypto_xof_shake256 + sodium_crypto_xof_shake256_init + sodium_crypto_xof_shake256_update + sodium_crypto_xof_shake256_squeeze + sodium_crypto_xof_turboshake128 + sodium_crypto_xof_turboshake128_init + sodium_crypto_xof_turboshake128_update + sodium_crypto_xof_turboshake128_squeeze + sodium_crypto_xof_turboshake256 + sodium_crypto_xof_turboshake256_init + sodium_crypto_xof_turboshake256_update + sodium_crypto_xof_turboshake256_squeeze + + + + The following functions expose the X-Wing KEM + (hybrid ML-KEM768+X25519, libsodium's recommended KEM). + They are available when PHP is built against libsodium 1.0.22 or later. + + + sodium_crypto_kem_keypair + sodium_crypto_kem_seed_keypair + sodium_crypto_kem_secretkey + sodium_crypto_kem_publickey + sodium_crypto_kem_enc + sodium_crypto_kem_dec + + + + + The following functions expose the ML-KEM768 (FIPS 203) + KEM. + They are available when PHP is built against libsodium 1.0.22 or later. + + + sodium_crypto_kem_mlkem768_keypair + sodium_crypto_kem_mlkem768_seed_keypair + sodium_crypto_kem_mlkem768_secretkey + sodium_crypto_kem_mlkem768_publickey + sodium_crypto_kem_mlkem768_enc + sodium_crypto_kem_mlkem768_dec + + + + + + + URI + + + + + Uri\Rfc3986\Uri::getUriType + + + Uri\WhatWg\Url::isSpecialScheme + + + + Uri\Rfc3986\Uri::getHostType + + + Uri\WhatWg\Url::getHostType + + + Uri\WhatWg\url_percent_encode + + + + + Zip + + + + ZipArchive::openString + + + ZipArchive::closeString + + + + + + + Using namespace as a class constant name is + deprecated. + + + + + + Returning from a finally block + + + + Using the return statement in a + finally block is now + deprecated. + + + + + + Nullable return type for __debugInfo() + + + Specifying a return type of + arraynull for + __debugInfo() is now + deprecated. + Specify array instead. + + + + + + Returning values from __construct() and __destruct() + + + + Returning values from + __construct() and + __destruct() is now + deprecated. + + + + Making __construct() + and __destruct() a + generator is now deprecated. + + + + + + Naming a function readonly + + + + Naming a function readonly is now deprecated. + + + + + + Third argument to define() + + + + Passing a third argument (case_insensitive) to + define is now deprecated. + + + + + + is_a() and is_subclass_of() with a string when allow_string is false + + + + + Calling is_a or is_subclass_of + with a string as the first argument when + allow_string is &false; is now deprecated. + + + + + + metaphone() + + + The metaphone function is deprecated. + Use a userland phonetic matching library instead. + + + + + + + More than 16 filters in a php://filter URL + + + Using more than 16 filters in a + php://filter URL without configuring + the filter.max_filter_count stream context option now + emits an E_DEPRECATED warning. + Use stream_filter_append or configure this option + explicitly. + + + + + + + Passing objects to array_walk(), array_walk_recursive(), and http_build_query() + + + Passing an object to array_walk and + array_walk_recursive is now deprecated. + Use get_object_vars on the object instead. + + + + + Passing an object as the data argument to + http_build_query is now deprecated. + The interpretation of object values within data as + arrays is also deprecated. + Convert objects to arrays with get_object_vars + before calling the function. + + + + + + + is_double(), is_long(), is_integer(), and doubleval() + + + The is_double function is now deprecated. + Use is_float instead. + + + + + The is_long and is_integer + functions are now deprecated. + Use is_int instead. + + + + + + The doubleval function is now deprecated. + Use floatval instead. + + + + + + + strcoll() and SORT_LOCALE_STRING + + + The strcoll function is now deprecated. + Use Collator::compare instead. + + + + + The SORT_LOCALE_STRING constant for the family of + sort functions is now deprecated. + Use one of the following methods instead: + + + + Collator::sort + Collator::asort + Collator::sortWithSortKeys + + + + + + + + + Bzip2 + + + Passing an object as the parameters of the + bzip2.compress and + bzip2.decompress stream filters is now deprecated. + Use get_object_vars on the object instead. + + + + + + + GMP + + + The shift (<<, >>) and + exponentiation (**) operators on + GMP objects now emit a deprecation warning when + converting a float right operand to int loses + precision. + + + + + + MBString + + + The mbregex functions + (mb_ereg and related functions) have been deprecated, + because the underlying Oniguruma library is no longer maintained. + + + + + Passing objects to mb_convert_variables is now + deprecated. + + + + + + + MySQLi + + + The mysqli_get_charset function and + mysqli::get_charset method are now deprecated. + + + + + The mysqli_stmt_init function, + mysqli::stmt_init method, and calling the + mysqli_stmt::__construct constructor without + providing the query parameter are now deprecated. + + + + + + + Reflection + + + Calling ReflectionProperty::setValue or + ReflectionProperty::setRawValue with an object + that is not an instance of the class on which the property was declared + is now deprecated. + + + + + Calling ReflectionMethod::invoke or + ReflectionMethod::invokeArgs with an object and a + static method is now deprecated. + + + + + + + Session + + + Passing an object that does not implement the + SessionIdInterface::create_sid and + SessionUpdateTimestampHandlerInterface::validateId + methods to session_set_save_handler is now + deprecated. + + + + + A deprecation is now emitted when implementing + SessionHandlerInterface on a class which + doesn't define the create_sid() or + validateId() methods, as those will be moved from + SessionUpdateTimestampHandlerInterface and + SessionIdInterface to + SessionHandlerInterface. + + + + + + + SPL + + + The spl_classes function is now deprecated. + Use ReflectionExtension::getClassNames instead. + + + + + The spl_object_hash function is now deprecated. + Use spl_object_id instead. + + + + + The following ArrayIterator methods are now + deprecated: + + + + ArrayIterator::getFlags + ArrayIterator::setFlags + ArrayIterator::asort + ArrayIterator::ksort + ArrayIterator::uasort + ArrayIterator::uksort + ArrayIterator::natsort + ArrayIterator::natcasesort + ArrayIterator::unserialize + ArrayIterator::serialize + + + + + The following SplFileObject methods are now + deprecated: + + + + SplFileObject::fgetcsv + SplFileObject::fputcsv + SplFileObject::setCsvControl + SplFileObject::getCsvControl + + + + + + + Zlib + + + Passing an object as the parameters of the + zlib.deflate and zlib.inflate + stream filters is now deprecated. + Use get_object_vars on the object instead. + + + + + Passing an object as the options argument to + deflate_init and inflate_init + is now deprecated. + Use get_object_vars on the object instead. + + + + + - Using namespace as a class constant name is - deprecated. + Declaring a class constant + named namespace is now deprecated. + namespace is a semi-reserved keyword, and the name is + being reserved for possible future syntax such as a + ::namespace pseudo-constant analogous to + ::class. + Methods and static properties named namespace are + not affected. + Rename the constant, for example to NAMESPACE_NAME. @@ -21,22 +28,48 @@ - Using the return statement in a - finally block is now - deprecated. + Using the return statement inside a + finally block is now + deprecated, and emits a compile-time deprecation notice. + Such a return silently discards an exception thrown + by, or overwrites the value returned from, the associated + try or catch block, so failures + vanish without a trace. + Move the return out of the finally + block instead; the same result can always be expressed without it. + + + + + + Nullable return type for __debugInfo() - Specifying a return type of + Declaring a return type of arraynull for __debugInfo() is now deprecated. - Specify array instead. + Returning &null; from this method was + already + deprecated in PHP 8.5, so the nullable return type no longer + describes valid behaviour. + Declare array instead. @@ -46,15 +79,21 @@ - Returning values from - __construct() and + Returning a value from + __construct() or __destruct() is now - deprecated. + deprecated, and emits a compile-time deprecation notice. + These methods cannot declare a return type, and their return value can + never be observed during normal use, which made returning a value + confusing at best. + Using return; without a value to skip the remaining + logic is still allowed, as is calling these methods manually. - Making __construct() - and __destruct() a + For the same reason, using yield to make + __construct() or + __destruct() a generator is now deprecated. @@ -65,7 +104,47 @@ - Naming a function readonly is now deprecated. + Declaring a function named readonly is now deprecated. + readonly + is a reserved keyword; a lexer exception was added in PHP 8.1 solely to + keep an existing WordPress function of that name working, and no other + keyword in PHP receives such special treatment. + Rename the function. + + + + + + Using let, is, or _ as an identifier + + + + + + + Using let or is as the name of a + class, interface, trait, enum, function, or constant (including via + define) is now deprecated, as is using either as + the alias in a class_alias call or in a + use, use function, or + use const declaration. + The names are being reserved as keywords for potential future features: + let for block scoping and is for + pattern matching. + Rename the affected symbols. + + + + The + deprecation + of _ as a class name in PHP 8.4 is extended to + constants: declaring a constant named _ with + const or define, and aliasing a + class or constant to _ in a use + declaration, are now deprecated. + Functions named _, including the + _ alias of gettext, are not + affected. @@ -75,8 +154,14 @@ - Passing a third argument (case_insensitive) to + Passing the case_insensitive argument to define is now deprecated. + Case-insensitive constants were removed in PHP 8.0, since when the + argument has been ignored. + Explicitly passing &false; now emits a deprecation notice. + Passing &true; continues to emit a warning, whose message now states + that this will become an error in PHP 9.0. + Omit the argument. @@ -88,99 +173,141 @@ Calling is_a or is_subclass_of - with a string as the first argument when + with a string as the first argument while allow_string is &false; is now deprecated. + In that case the functions always return &false;, even when the class + is already loaded, so such a call indicates a bug. + To avoid triggering autoloading, check class_exists + with autoloading disabled first, and then call the function with + allow_string set to &true;. metaphone() + - The metaphone function is deprecated. - Use a userland phonetic matching library instead. - + The metaphone function is now deprecated. + It implements the original 1990 Metaphone algorithm, which is limited to + English pronunciation rules and has long been superseded by Double + Metaphone and Metaphone 3. + Phonetic algorithms are language-specific and frequently updated, so + they are better served by a userland library; use one instead. More than 16 filters in a php://filter URL + Using more than 16 filters in a php://filter URL without configuring the filter.max_filter_count stream context option now - emits an E_DEPRECATED warning. - Use stream_filter_append or configure this option - explicitly. - + emits a deprecation notice. + Long filter chains have no known legitimate use, but are the basis of + a class of attacks that turn a local file inclusion or an arbitrary file + read into remote code execution. + When filter.max_filter_count is set explicitly, + exceeding it is already an error: opening the stream fails with a + warning. + + + + Code that needs more filters should either add them with + stream_filter_append or + stream_filter_prepend, which are not limited, or + raise the limit through the context option, for example globally with + stream_context_set_default. Passing objects to array_walk(), array_walk_recursive(), and http_build_query() + + - Passing an object to array_walk and + Passing an object as the array argument to + array_walk or array_walk_recursive is now deprecated. - Use get_object_vars on the object instead. - + A small number of functions silently interpret an object as the array + of its visible properties. + Modifying such properties through a by-reference callback violates + readonly + semantics and can corrupt enum cases, and + array_walk_recursive does not recurse into nested + objects anyway. + Call get_object_vars on the object first and pass + the resulting array. Passing an object as the data argument to http_build_query is now deprecated. - The interpretation of object values within data as - arrays is also deprecated. - Convert objects to arrays with get_object_vars - before calling the function. - + Objects encountered as values within data now + also emit a deprecation notice when they are interpreted as arrays. + Treating objects as arrays has been a recurring source of confusion, + in particular for Stringable objects, + which users expect to be converted to a string instead. + Convert objects to arrays with get_object_vars, + recursively if necessary, before calling the function. is_double(), is_long(), is_integer(), and doubleval() + + + + - - The is_double function is now deprecated. - Use is_float instead. - - - - - The is_long and is_integer - functions are now deprecated. - Use is_int instead. - - - + + Following the + deprecation + of the non-canonical cast names in PHP 8.5, the function aliases + that carry the same outdated type names are now deprecated. + They behave identically to their canonical counterparts, which should + be used instead: - - The doubleval function is now deprecated. - Use floatval instead. - - + + is_double => is_float + is_long => is_int + is_integer => is_int + doubleval => floatval + + strcoll() and SORT_LOCALE_STRING + + The strcoll function is now deprecated. - Use Collator::compare instead. - + It compares strings according to the LC_COLLATE + setting of the current locale, which is global process state set via + setlocale that any library can change, it is not + binary safe unlike every other string comparison function, and some + locales do not implement correct collation rules. + Use Collator::compare from the + intl extension instead, which is + accurate and has up-to-date collation rules. - The SORT_LOCALE_STRING constant for the family of - sort functions is now deprecated. - Use one of the following methods instead: - + The SORT_LOCALE_STRING flag of the sort functions + is now deprecated for the same reasons, as it sorts using + strcoll. + Use one of the following methods of the + Collator class instead: Collator::sort @@ -199,8 +326,10 @@ Passing an object as the parameters of the bzip2.compress and - bzip2.decompress stream filters is now deprecated. - Use get_object_vars on the object instead. + bzip2.decompress stream filters is now deprecated, as only an + associative array is documented and supported. + Call get_object_vars on the object first and pass + the resulting array. @@ -212,9 +341,10 @@ The shift (<<, >>) and exponentiation (**) operators on - GMP objects now emit a deprecation warning when - converting a float right operand to int loses - precision. + GMP objects now emit a deprecation notice when the + right operand is a float whose conversion to + int loses precision, consistent with the deprecation of + implicit lossy float to int conversions elsewhere in the language. @@ -222,16 +352,52 @@ MBString - - The mbregex functions - (mb_ereg and related functions) have been deprecated, - because the underlying Oniguruma library is no longer maintained. + + The mbregex functions have been deprecated, because the underlying + Oniguruma library is no longer maintained; its maintenance ended in + April 2025. + The functions will be removed in PHP 9.0. + For most use cases the PCRE functions + with the u modifier are a suitable replacement. + The affected functions are: + + + mb_ereg + mb_ereg_match + mb_ereg_replace + mb_ereg_replace_callback + mb_ereg_search + mb_ereg_search_getpos + mb_ereg_search_getregs + mb_ereg_search_init + mb_ereg_search_pos + mb_ereg_search_regs + mb_ereg_search_setpos + mb_eregi + mb_eregi_replace + mb_regex_encoding + mb_regex_set_options + mb_split + + + + + The MB_ONIGURUMA_VERSION constant and the + mbstring.regex_retry_limit + and + mbstring.regex_stack_limit + INI directives are deprecated along with them. - Passing objects to mb_convert_variables is now - deprecated. + Passing an object as the vars argument to + mb_convert_variables is now deprecated, as objects + are silently interpreted as the array of their visible properties. + Call get_object_vars on the object first, or use + mb_convert_encoding, which converts arrays + recursively and returns the result instead of modifying its argument + in place. @@ -241,16 +407,32 @@ MySQLi - The mysqli_get_charset function and - mysqli::get_charset method are now deprecated. + The mysqli_get_charset function and the + mysqli::get_charset method are now deprecated, + without replacement. + They expose internal implementation details of the character set that + have been meaningless since the switch to mysqlnd; in particular the + reported collation does not correspond to the collation defined by the + server. + To get the name of the current character set, use + mysqli_character_set_name or + mysqli::character_set_name. - The mysqli_stmt_init function, - mysqli::stmt_init method, and calling the - mysqli_stmt::__construct constructor without - providing the query parameter are now deprecated. + The mysqli_stmt_init function and the + mysqli::stmt_init method are now deprecated. + They create an empty statement object that still has to be prepared + before use, and are a source of statement objects left in an + inconsistent state. + Use mysqli_prepare or + mysqli::prepare instead, which prepare the + statement in one step. + For the same reason, calling the + mysqli_stmt::__construct constructor without the + query parameter is now deprecated; pass the query + to the constructor instead. @@ -264,13 +446,20 @@ ReflectionProperty::setRawValue with an object that is not an instance of the class on which the property was declared is now deprecated. + Unlike the other ReflectionProperty methods, which + throw for such objects, these methods silently set a property on the + unrelated object, which is no better than a normal assignment and + conceptually wrong. - Calling ReflectionMethod::invoke or - ReflectionMethod::invokeArgs with an object and a + Passing an object to ReflectionMethod::invoke or + ReflectionMethod::invokeArgs when invoking a static method is now deprecated. + Static methods have no $this, so the object was + ignored entirely and never validated. + Pass &null; instead. @@ -280,23 +469,30 @@ Session - Passing an object that does not implement the + Passing an object that does not implement both the SessionIdInterface::create_sid and SessionUpdateTimestampHandlerInterface::validateId methods to session_set_save_handler is now - deprecated. + deprecated, regardless of which interfaces the object declares. + These methods are required for a save handler to behave correctly under + session.use_strict_mode, + which is + enabled by default as of + PHP 8.6 and mitigates session fixation. - A deprecation is now emitted when implementing - SessionHandlerInterface on a class which - doesn't define the create_sid() or - validateId() methods, as those will be moved from - SessionUpdateTimestampHandlerInterface and - SessionIdInterface to - SessionHandlerInterface. - + Accordingly, a deprecation notice is now emitted when a class implements + SessionHandlerInterface without defining + the create_sid() or validateId() + methods. + In PHP 9.0 these methods will be moved from + SessionIdInterface and + SessionUpdateTimestampHandlerInterface into + SessionHandlerInterface, where they will be + required. + Implement both methods on custom save handlers now. @@ -306,19 +502,32 @@ The spl_classes function is now deprecated. + No other extension exposes such a function, and the Reflection extension + is always available. Use ReflectionExtension::getClassNames instead. The spl_object_hash function is now deprecated. + Since PHP 8.1 its return value has been nothing more than a reformatted + spl_object_id, and the name is misleading as the + value is not derived from the contents of the object. + The string form is also error-prone: two hashes can compare loosely equal + because both are numeric strings. Use spl_object_id instead. The following ArrayIterator methods are now - deprecated: + deprecated. + They only exist because ArrayIterator historically + shared its implementation with ArrayObject; most + of them make little sense on an iterator and prevent optimizing its + implementation. + The corresponding ArrayObject methods are not + deprecated. @@ -336,8 +545,13 @@ - The following SplFileObject methods are now - deprecated: + The CSV methods of SplFileObject are now + deprecated. + Their historical design inconsistencies, further exposed by named + arguments, have made them increasingly difficult to maintain, and CSV + handling does not naturally belong in SplFileObject. + Use fgetcsv and fputcsv on a + stream instead. @@ -356,16 +570,20 @@ Passing an object as the parameters of the zlib.deflate and zlib.inflate - stream filters is now deprecated. - Use get_object_vars on the object instead. + stream filters is now deprecated, as only an associative array is + documented and supported. + Call get_object_vars on the object first and pass + the resulting array. Passing an object as the options argument to - deflate_init and inflate_init - is now deprecated. - Use get_object_vars on the object instead. + deflate_init or inflate_init + is now deprecated, as objects are silently interpreted as the array of + their visible properties. + Call get_object_vars on the object first and pass + the resulting array. From 8f5a487393a3f21e0379b47b4136e567d2d1d88f Mon Sep 17 00:00:00 2001 From: Jordi Kroon Date: Wed, 30 Sep 2026 19:51:39 +0200 Subject: [PATCH 05/17] Document Windows changes --- appendices/migration86/windows-support.xml | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/appendices/migration86/windows-support.xml b/appendices/migration86/windows-support.xml index e4e911aa539e..1ec36100abd5 100644 --- a/appendices/migration86/windows-support.xml +++ b/appendices/migration86/windows-support.xml @@ -2,6 +2,38 @@ Windows Support + + Core + + + The official Windows builds now use Visual Studio 2026 (VS18). + + + + + + LibXML + + + The libxml2 library used by the official Windows builds has been upgraded + to version 2.15.3. + As a result, DOMDocument::$documentURI for documents + loaded from a local file now contains a native filesystem path instead of + a file URI. + + + + + + OpenSSL + + + The OpenSSL library used by the official Windows builds has been upgraded + to OpenSSL 4. + + + + + + + + +timeout); // int(30) +]]> + + + + + + + Reference assignment on WeakMap + + + It is now possible to use reference assignment on a + WeakMap without the key needing to be present + beforehand. + + + + + + __debugInfo() on enums + + + It is now possible to define the + __debugInfo() + magic method on enums. + + + + + + + <code>#[\Override]</code> for class constants + + + The Override attribute can now be applied to + class constants, including enum cases. + + + + + + + Partial function application + + + Added support for partial function application. A call in which one or + more arguments are replaced by the ? placeholder, or + the remaining arguments by the ... placeholder, + creates a Closure that accepts the missing + arguments. + + + + + + + + + + + + + Mutating objects stored in constants + + + Objects stored in constants or class constants can now be mutated + directly via OBJ->prop = $val. + + + + + + + Endianness modifiers for pack() and unpack() + + + pack and unpack now accept the + < and > endianness modifiers + on the signed and unsigned integer format codes. + + + + + pack and unpack now accept the + < and > endianness modifiers + on the float and double format codes. + + + + + + + + + cURL + + + The array returned by curl_getinfo now includes a new + "size_delivered" key, which indicates the total number of + bytes passed to the download write callback. + This value can also be obtained by passing + CURLINFO_SIZE_DELIVERED as the + option parameter. + Requires libcurl 8.20.0 or later. + + + + Added CURLOPT_SEEKFUNCTION to register a callback that + repositions a streamed request body, so libcurl can rewind and resend it on + a redirect, multi-pass authentication, or a retried reused connection + instead of failing with CURLE_SEND_FAIL_REWIND. + The callback receives the CurlHandle, offset and + origin, and must return one of CURL_SEEKFUNC_OK, + CURL_SEEKFUNC_FAIL or + CURL_SEEKFUNC_CANTSEEK. + + + + + + Date + + + Added the Time\Duration class. + + + + + + + FileInfo + + + finfo_file now works with remote streams. + + + + + + GMP + + + Added gmp_powm_sec for side-channel quiet modular + exponentiation. + Requires GNU MP 5.0.0 or later; it is not available on official Windows + builds using MPIR. + + + + Added gmp_prevprime to get the largest prime smaller + than the given number. + The optional definitely_prime output parameter + indicates whether the returned number is definitely prime, as opposed to + probably prime. + A ValueError is thrown if no such prime + exists. + This function is only available when PHP is built against GNU MP 6.3.0 or + later; it is not available on official Windows builds using MPIR. + + + + + + Intl + + + Added the static methods + IntlDatePatternGenerator::getSkeleton and + IntlDatePatternGenerator::getBaseSkeleton to + generate the unique skeleton and base skeleton for a date/time pattern. + + + + Added Locale::getDisplayKeyword and + Locale::getDisplayKeywordValue, with the aliases + locale_get_display_keyword and + locale_get_display_keyword_value, respectively. + + + + + Added the IntlNumberRangeFormatter class to format + an interval of two numbers with a given skeleton, locale, + IntlNumberRangeFormatter::COLLAPSE_AUTO, + IntlNumberRangeFormatter::COLLAPSE_NONE, + IntlNumberRangeFormatter::COLLAPSE_UNIT, + IntlNumberRangeFormatter::COLLAPSE_ALL collapse and + IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE, + IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE, + IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY + and IntlNumberRangeFormatter::IDENTITY_FALLBACK_RANGE + identity fallbacks. + It is supported as of ICU 63. + + + + Added SpoofChecker::areBidiConfusable to check + whether two strings are confusable for a given text direction, along with + the SpoofChecker::LTR and + SpoofChecker::RTL direction constants. + It is supported as of ICU 74. + + + + Added SpoofChecker::getBidiSkeleton to generate a + confusable skeleton for a given text direction. + It is supported as of ICU 74. + + + + Added SpoofChecker::getSkeleton to generate a + confusable skeleton for a given string. + + + + + + IO + + + Added a new polling API, consisting of the + Io\Poll\Context and + Io\Poll\Watcher classes, the + Io\Poll\Backend and + Io\Poll\Event enums, the + Io\Poll\Handle interface, and the + StreamPollHandle class to watch streams. + + + + + + + JSON + + + Added extra information about the error location to the error messages + returned by json_last_error_msg and to the message of + JsonException. + + + + + + OpenSSL + + + Added TLS session resumption support for streams with + the new SSL context options + session_data, session_new_cb, + session_cache, session_cache_size, + session_timeout, session_id_context, + session_get_cb, session_remove_cb, + and num_tickets. + This allows saving and restoring client sessions across requests, + implementing custom server-side session storage, and controlling session + cache behavior. + + + + + Added TLS external PSK support for + streams with the new SSL context + options psk_client_cb and + psk_server_cb. + This allows setting and receiving pre-shared keys. + + + + Added TLS 1.3 early data (0-RTT) support for streams. + Clients send early data with the early_data + SSL context option; servers accept it + with max_early_data and receive it through the + early_data_cb callback. + The outcome is reported as "accepted", + "rejected" or "not_sent" in the + "early_data" key of the "crypto" + entry of the stream_get_meta_data array. + + + + + + PDO_PGSQL + + + Added Pdo\Pgsql::ATTR_CHUNK_SIZE, the number of rows a + statement fetches per chunk. + A value of 1 or more enters the lazy fetch mode of + PDO::ATTR_PREFETCH => 0. + Setting PDO::ATTR_PREFETCH replaces the chunk size. + Statements that are prepared with neither it nor + PDO::ATTR_PREFETCH fall back to the value set on the + connection. + Requires libpq 17 or later. + + + + + + Phar + + + Overriding the SplFileInfo::getMTime and + SplFileInfo::getPathname methods now influences + the result of the Phar::buildFromDirectory and + Phar::buildFromIterator family of methods. + This makes it possible to override the timestamp and names of files. + + + + + + SNMP + + + It is now possible to use AES192, + AES192C, AES256, and + AES256C as SNMPv3 security protocols if the underlying + library supports them. + + + + + It is now possible to reset the MIB tree using the new + snmp_init_mib function. + + + + + Additional MIB parsing and output control functionality + has been exposed via the snmp_set_mib_option, + snmp_set_output_option, and + snmp_set_string_output_format functions, the + SNMP::$numeric_index, + SNMP::$numeric_timeticks, + SNMP::$extended_index, + SNMP::$dont_print_units, + SNMP::$escape_quotes, and + SNMP::$print_hex_text properties, and the + SNMP::setOidOutputFormat and + SNMP::setStringOutputFormat methods. + + + + + + + Streams + + + Added a new stream errors API including the + StreamError and + StreamException classes, the + StreamErrorStore, + StreamErrorMode, and + StreamErrorCode enums, and the + stream_last_errors and + stream_clear_errors functions. + It is controlled using the error_mode, + error_store and error_handler + stream context options. + + + + + Added the filter.max_filter_count stream context option + for php://filter URLs. + When set, opening the stream fails with a warning if the URL would add more + filters than the configured value. + Negative values disable the check. + + + + + Added the socket context option + so_reuseaddr that allows disabling address reuse + (SO_REUSEADDR) and explicitly uses + SO_EXCLUSIVEADDRUSE on Windows. + + + + Added the socket context options + so_keepalive, tcp_keepidle, + tcp_keepintvl and tcp_keepcnt that + allow setting socket keepalive options. + + + + Added the socket context option + so_linger that sets SO_LINGER on + TCP sockets. + A positive value enables lingering for that many seconds, zero or a + negative value disables it. + Values above 65535 are clamped as the linger time is limited to an + unsigned short on some platforms. + + + + Added the socket context options + so_rcvbuf and so_sndbuf that set the + socket receive and send buffer sizes in bytes + (SO_RCVBUF and SO_SNDBUF) on + TCP and UDP sockets. + The value must be an integer between 1 and 2147483647, any other value + makes the stream creation fail. + The operating system may round, cap or otherwise adjust the requested size, + and may stop sizing that buffer automatically, so the size read back can + differ from the one requested. + + + + Filtered streams can now be cast to file descriptors for use with + stream_select. + + + + Added the "write_seek_mode" filter parameter for the + bz2, iconv, zlib, and string stream + filters. + This parameter must be set via an associative array where the key is + "write_seek_mode" and the value is one of the following + strings: "preserve", "reset", or + "strict". + + + + + + URI + + + Added Uri\Rfc3986\Uri::getUriType and + Uri\WhatWg\Url::isSpecialScheme. + + + + + Added Uri\Rfc3986\Uri::getHostType and + Uri\WhatWg\Url::getHostType. + + + + + Added the Uri\Rfc3986\UriBuilder and + Uri\WhatWg\UrlBuilder classes. + + + + + Added Uri\WhatWg\url_percent_encode. + + + + + + + + $this->name, 'symbol' => $this->value]; + } +} + +var_dump(Suit::Hearts); +]]> + + &example.outputs; + + + string(6) "Hearts" + ["symbol"]=> + string(1) "H" +} +]]> + + + @@ -60,9 +109,34 @@ var_dump($config->timeout); // int(30) The Override attribute can now be applied to class constants, including enum cases. + As with methods and properties, a compile-time error is raised if no + matching constant exists in a parent class or implemented interface. + + + + + + @@ -81,13 +155,22 @@ var_dump($config->timeout); // int(30) @@ -103,6 +186,20 @@ var_dump($addOne(5)); // int(6) + + +debug = true; + +var_dump(CONFIG->debug); // bool(true) +]]> + + + @@ -110,18 +207,26 @@ var_dump($addOne(5)); // int(6) pack and unpack now accept the - < and > endianness modifiers - on the signed and unsigned integer format codes. + < (little-endian) and > + (big-endian) modifiers after the signed and unsigned integer format codes, + and after the float and double format codes. - - - - pack and unpack now accept the - < and > endianness modifiers - on the float and double format codes. + + +', 1)), PHP_EOL; // Prints "00000001" +echo bin2hex(pack('l<', 1)), PHP_EOL; // Prints "01000000" +echo bin2hex(pack('f>', 1.5)), PHP_EOL; // Prints "3fc00000" + +var_dump(unpack('s>value', "\xff\xfe")); // ["value" => int(-2)] +]]> + + + @@ -213,20 +318,25 @@ var_dump($addOne(5)); // int(6) - + Added the IntlNumberRangeFormatter class to format - an interval of two numbers with a given skeleton, locale, - IntlNumberRangeFormatter::COLLAPSE_AUTO, - IntlNumberRangeFormatter::COLLAPSE_NONE, - IntlNumberRangeFormatter::COLLAPSE_UNIT, - IntlNumberRangeFormatter::COLLAPSE_ALL collapse and - IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE, - IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE, - IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY - and IntlNumberRangeFormatter::IDENTITY_FALLBACK_RANGE - identity fallbacks. + an interval of two numbers with a given skeleton and locale. It is supported as of ICU 63. - + The collapse behavior is one of: + + IntlNumberRangeFormatter::COLLAPSE_AUTO + IntlNumberRangeFormatter::COLLAPSE_NONE + IntlNumberRangeFormatter::COLLAPSE_UNIT + IntlNumberRangeFormatter::COLLAPSE_ALL + + The identity fallback is one of: + + IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE + IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE + IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY + IntlNumberRangeFormatter::IDENTITY_FALLBACK_RANGE + + Added SpoofChecker::areBidiConfusable to check @@ -252,16 +362,16 @@ var_dump($addOne(5)); // int(6) IO - - Added a new polling API, consisting of the - Io\Poll\Context and - Io\Poll\Watcher classes, the - Io\Poll\Backend and - Io\Poll\Event enums, the - Io\Poll\Handle interface, and the - StreamPollHandle class to watch streams. + + Added a new polling API, consisting of: + + The Io\Poll\Context and Io\Poll\Watcher classes + The Io\Poll\Backend and Io\Poll\Event enums + The Io\Poll\Handle interface + The StreamPollHandle class to watch streams + - + @@ -279,19 +389,25 @@ var_dump($addOne(5)); // int(6) OpenSSL - - Added TLS session resumption support for streams with - the new SSL context options - session_data, session_new_cb, - session_cache, session_cache_size, - session_timeout, session_id_context, - session_get_cb, session_remove_cb, - and num_tickets. + + Added TLS session resumption support for streams. This allows saving and restoring client sessions across requests, implementing custom server-side session storage, and controlling session - cache behavior. + cache behavior, using the following new + SSL context options: + + session_data + session_new_cb + session_cache + session_cache_size + session_timeout + session_id_context + session_get_cb + session_remove_cb + num_tickets + - + Added TLS external PSK support for @@ -362,41 +478,42 @@ var_dump($addOne(5)); // int(6) - + Additional MIB parsing and output control functionality - has been exposed via the snmp_set_mib_option, - snmp_set_output_option, and - snmp_set_string_output_format functions, the - SNMP::$numeric_index, - SNMP::$numeric_timeticks, - SNMP::$extended_index, - SNMP::$dont_print_units, - SNMP::$escape_quotes, and - SNMP::$print_hex_text properties, and the - SNMP::setOidOutputFormat and - SNMP::setStringOutputFormat methods. + has been exposed via: + + snmp_set_mib_option + snmp_set_output_option + snmp_set_string_output_format + SNMP::$numeric_index + SNMP::$numeric_timeticks + SNMP::$extended_index + SNMP::$dont_print_units + SNMP::$escape_quotes + SNMP::$print_hex_text + SNMP::setOidOutputFormat + SNMP::setStringOutputFormat + - + Streams - - Added a new stream errors API including the - StreamError and - StreamException classes, the - StreamErrorStore, - StreamErrorMode, and - StreamErrorCode enums, and the - stream_last_errors and - stream_clear_errors functions. + + Added a new stream errors API, consisting of: + + The StreamError and StreamException classes + The StreamErrorStore, StreamErrorMode, and StreamErrorCode enums + The stream_last_errors and stream_clear_errors functions + It is controlled using the error_mode, error_store and error_handler stream context options. - + Added the filter.max_filter_count stream context option @@ -449,15 +566,19 @@ var_dump($addOne(5)); // int(6) stream_select. - + Added the "write_seek_mode" filter parameter for the bz2, iconv, zlib, and string stream filters. This parameter must be set via an associative array where the key is "write_seek_mode" and the value is one of the following - strings: "preserve", "reset", or - "strict". - + strings: + + "preserve" + "reset" + "strict" + + From 98db2ed72fe9a35763a3379eb2484bf700962da3 Mon Sep 17 00:00:00 2001 From: Jordi Kroon Date: Wed, 30 Sep 2026 20:14:00 +0200 Subject: [PATCH 09/17] Document incompatibilities features --- appendices/migration86/incompatible.xml | 841 ++++++++++++++++++++++++ 1 file changed, 841 insertions(+) diff --git a/appendices/migration86/incompatible.xml b/appendices/migration86/incompatible.xml index 432ff047b489..462476b926c9 100644 --- a/appendices/migration86/incompatible.xml +++ b/appendices/migration86/incompatible.xml @@ -2,6 +2,847 @@ Backward Incompatible Changes + + PHP Core + + + By-reference foreach after array compaction + + + By-reference foreach loops may now visit previously + skipped elements after array compaction. + Internal pointers on deleted elements now move to the next surviving + element during copy-on-write. + + + + + + Null coalescing and empty() on magic properties + + + ?? and empty on a magic property + no longer call __get() when + __isset() has materialized the + property by writing into the property table. + The freshly-written value is returned directly. + isset is unaffected. + + + + + + String conversion in array_intersect() + + + array_intersect with at least two arrays now converts + values to strings while scanning its inputs instead of during sort + comparisons. + This can change the number and order of conversion warnings and + __toString() calls, which conversion + exception is reached, and the result for stateful + __toString() implementations. + Argument types are validated before checking for empty arrays or + converting values, so an invalid later argument can suppress conversion + side effects from earlier arrays. + Values are not converted if any input array is empty. + + + + + + Form feed trimmed by default + + + Form feed (\f) is now added to the default trimmed + characters of trim, rtrim and + ltrim. + + + + + + + New ValueError and TypeError exceptions + + + array_filter now raises a + ValueError when an invalid + mode argument value is passed. + + + + array_change_key_case now raises a + ValueError when an invalid + case argument value is passed. + + + + getenv and putenv now raise a + ValueError when the first argument contains + NUL bytes. + + + + dl now raises a + ValueError when the + extension_filename argument contains + NUL bytes. + + + + openlog now raises a + ValueError when the + prefix argument contains NUL + bytes. + + + + parse_str now raises a + ValueError when the + string argument contains NUL + bytes. + + + + setlocale now raises a + ValueError when a locale name contains + NUL bytes, instead of silently truncating it. + Arrays are now accepted only for the locales + argument. + Passing an array as a later variadic locale argument now throws a + TypeError. + Passing any additional locale arguments when + locales is an array now throws an + ArgumentCountError. + + + + linkinfo now raises a + ValueError when the + path argument is empty. + + + + pathinfo now raises a + ValueError when an invalid + flags argument value is passed. + + + + scandir now raises a + ValueError when an invalid + sorting_order argument value is passed. + + + + number_format now raises a + ValueError when + decimals is outside the integer range instead of + silently clamping very large positive values. + + + + sleep now raises a + ValueError when + seconds is greater than the platform limit + (UINT_MAX seconds, or UINT_MAX / 1000 + seconds on Windows) instead of allowing the value to overflow. + + + + usleep now raises a + ValueError when + microseconds is greater than + UINT_MAX instead of allowing the value to overflow. + + + + proc_open now raises a + ValueError when the + cwd argument contains NUL bytes. + + + + The following functions now raise a + ValueError when the + filename argument contains NUL + bytes: + + + fileperms + fileinode + filesize + fileowner + filegroup + fileatime + filemtime + filectime + filetype + is_writable + is_readable + is_executable + is_file + is_dir + is_link + file_exists + lstat + stat + + + + + + + Notice on imprecise number conversion + + + base_convert, bindec, + hexdec and octdec now raise a + notice when they cannot precisely convert the given number. + + + + + + Endianness modifiers in unpack() format names + + + unpack now reads a < or + > immediately following a format code as an + endianness modifier rather than as the first character of the element + name. + Formats such as "s<value" now produce the key + "value" instead of "<value", and + "C>name" raises a + ValueError because the C + format code accepts no endianness modifier. + A name starting with these characters is unaffected when a repeater + precedes it, as in "s1<value". + + + + + + + + + COM + + + It is no longer possible to clone variant objects, + because the cloning behavior was ill-defined. + + + + + + cURL + + + The callback registered with CURLOPT_READFUNCTION now + throws a ValueError when returning an + integer other than 0, + CURL_READFUNC_ABORT or + CURL_READFUNC_PAUSE. + + + + + + DOM + + + Properties previously documented as read-only (e.g. + DOMNode::$nodeType, + DOMDocument::$xmlEncoding, + DOMEntity::$actualEncoding, + DOMEntity::$encoding, + DOMEntity::$version) are now declared with + asymmetric + visibility (public private(set)). + Attempts to write to them from outside the class now raise + Cannot modify private(set) property class::$prop from global scope + instead of the prior readonly modification error. + ReflectionProperty::isWritable also reports these + properties accurately. + + + + Array access on Dom\DtdNamedNodeMap objects now + returns &null; for negative integer indexes instead of returning the first + node. + + + + Array access on Dom\DtdNamedNodeMap objects now + raises a ValueError when the integer index + is greater than PHP_INT_MAX instead of overflowing + to a smaller index. + + + + + + FTP + + + ftp_nb_fget, ftp_nb_fput, + ftp_nb_get and ftp_nb_put now + throw an Error when the connection is + already transferring, instead of emitting a warning and returning &false;. + ftp_close already throws on the same condition. + + + + + + GD + + + imagesetstyle, imagefilter and + imagecrop filter the types and values of their array + arguments and raise a TypeError or + ValueError accordingly. + + + + imageaffinematrixget now enforces the documented + arrayfloat type for + the options parameter, including the corresponding + weak and strict typing behavior. + + + + + + GMP + + + gmp_fact now throws a + ValueError if num + does not fit into an unsigned long. + + + + gmp_pow, gmp_binomial, + gmp_root and gmp_rootrem now + throw a ValueError if their second argument + does not fit into an unsigned long. + + + + The shift (<<, >>) and + exponentiation (**) operators on + GMP objects now throw a + ValueError when GMP + right operands are outside the unsigned long range, instead of silently + truncating them. + + + + GMP integer string parsing now throws a + ValueError for strings containing + NUL bytes, instead of silently truncating them. + + + + gmp_powm modulo-by-zero now raises a + DivisionByZeroError whose message includes + the function name and argument index (modulus). + + + + + + Intl + + + Passing a non-stringable object as a time zone to Intl + APIs that accept time zone objects or strings now + raises a TypeError instead of an + Error. + + + + IntlIterator::current now returns &null; when + called before the iterator is positioned, or after the iterator becomes + invalid, instead of exposing an undefined value. + + + + IntlBreakIterator::getLocale now raises a + ValueError when the type is neither + Locale::ACTUAL_LOCALE nor + Locale::VALID_LOCALE instead of returning &false;. + + + + MessageFormatter::parse and + MessageFormatter::parseMessage now return + PHP_INT_MIN as int, rather than + float, on 64-bit platforms when parsing integer values. + + + + The type parameter of + IntlBreakIterator::getPartsIterator has been + changed from string to int to match the + underlying implementation. + + + + UConverter::transcode now rejects + from_subst and to_subst option values + longer than 127 bytes instead of silently truncating the length before + passing it to ICU. + + + + ResourceBundle::get and + resourcebundle_get now report fallback-disabled + resource lookups with + without fallback to locale + instead of the malformed + without fallback from to locale. + + + + IntlDateFormatter::parse/datefmt_parse + and + IntlDateFormatter::localtime/datefmt_localtime + now raise a TypeError when the + offset argument is not of type int + instead of silently converting the value. + + + + Collator::sort, + collator_sort, + Collator::asort, and + collator_asort now report UTF-8/UTF-16 conversion + failures during comparison through the intl error mechanism and return + &false;. + With intl.use_exceptions + enabled, these failures throw an IntlException. + Previously, these paths emitted a warning and compared the value as an + empty string. + + + + + + MBString + + + Unicode data tables have been updated to Unicode 18.0. + + + + + + PCNTL + + + pcntl_alarm now raises a + ValueError if the + seconds argument is lower than zero or greater + than the platform's UINT_MAX. + + + + pcntl_exec now raises a + ValueError if the + args argument is not a list array. + + + + + + PCRE + + + preg_grep now returns &false; instead of a partial + array when a PCRE execution error occurs (e.g. malformed UTF-8 input with + the u modifier). + This is consistent with the other preg_* functions. + + + + + + PGSQL + + + pg_fetch_object now reports the + ValueError for a non-empty + constructor_args on a class without a constructor + on the constructor_args argument instead of + class. + Errors raised when the requested class is not instantiable (abstract, + interface, enum) now surface before the row is fetched. + + + + + + Phar + + + Phar::mungServer now raises a + ValueError when an invalid argument value + is passed instead of being silently ignored. + + + + Phar::addEmptyDir now rejects + "/.phar" paths in addition to ".phar" + paths, and raises the same + BadMethodCallException for attempts to + create the reserved magic ".phar" directory through + that form. + + + + Phar::addEmptyDir now treats non-magic names that + merely share the ".phar" prefix as ordinary + directories. + + + + Files are only automatically interpreted as Phar archives when included if + ".phar" occurs as an extension in the filename component + of their paths. + Previously, it could occur in a directory name or as part of an extension + such as ".pharma". + + + + + + Session + + + Setting session.cookie_path, + session.cookie_domain, or + session.cache_limiter to a + value containing NUL bytes now emits a warning and + leaves the setting unchanged. + Previously, NUL bytes were silently accepted: for + cookie_path and cookie_domain this + caused the SAPI to drop the + Set-Cookie header; for cache_limiter + the value was silently truncated at the NUL byte. + + + + session_module_name now throws a + ValueError if name + is a string containing NUL bytes. + + + + session_encode now returns an empty string instead of + &false; for empty sessions. + It only returns &false; now when the session data could not be encoded. + This mainly happens with the default serialization handler if a key + contains the pipe (|) character. + + + + When session.lazy_write is + enabled and a session handler implements + SessionUpdateTimestampHandlerInterface, + sessions that were read as empty and remain empty at write time will now + trigger SessionUpdateTimestampHandlerInterface::updateTimestamp + instead of SessionHandlerInterface::write. + Previously, SessionHandlerInterface::write was + always called for empty sessions because + session_encode returned &false;, bypassing the + lazy_write comparison. + Custom session handlers that rely on + SessionHandlerInterface::write being called with + empty data (e.g. to destroy the session) should implement the same logic + in their SessionUpdateTimestampHandlerInterface::updateTimestamp + method. + + + + The defaults of three session INI settings have changed to provide secure + behavior out of the box: + + + + + session.use_strict_mode + is now 1 (was 0). + Strict mode rejects uninitialized session IDs, mitigating session + fixation. + Custom session handlers that previously relied on accepting externally + supplied IDs without a corresponding storage entry must either implement + SessionUpdateTimestampHandlerInterface::validateId + and SessionIdInterface::create_sid, or + explicitly set this to 0. + + + session.cookie_httponly + is now 1 (was 0). + Session cookies are no longer accessible to JavaScript via + document.cookie. + Applications that read the session cookie from JavaScript must + explicitly set this to 0. + + + session.cookie_samesite + is now "Lax" (was unset). + Session cookies are no longer sent on cross-site requests other than + top-level navigations using safe HTTP methods. + Applications that depend on session cookies being sent on cross-site + POST submissions must explicitly set this to "None" + (and also set + session.cookie_secure + to 1). + + + + + + SessionHandler::validateId has been added and + delegates to the configured save handler. + A subclass that declares validateId() without a return + type now emits a deprecation notice for the tentative bool + return type. + A subclass that overrides SessionHandler::open + without calling parent::open() keeps its previous behavior + and emits a warning when an ID is validated. + + + + + + Shmop + + + shmop_open now raises a + ValueError when the + key argument is outside the platform's + key_t range instead of passing a truncated key to the + operating system. + + + + + + SimpleXML + + + SimpleXMLElement::__construct now raises a + ValueError when the + data argument contains NUL + bytes, matching simplexml_load_file. + With dataIsURL set, it previously truncated the + path at the first NUL byte. + Without it, the string went to libxml, which with default options rejects + a NUL on current versions but accepts the truncated + document on older ones and under LIBXML_RECOVER. + + + + + + SOAP + + + The "classmap" option of + SoapClient and SoapServer + now rejects arrays containing integer keys. + Previously, sparse integer-keyed and mixed-keyed arrays could be accepted. + SoapClient now throws a + TypeError for non-array + "classmap" options and a + ValueError for arrays containing integer + keys, also when the "exceptions" option is disabled. + + + + WSDL/XML Schema parsing now rejects out-of-range integer values for + occurrence constraints and integer restriction facets. + Negative minOccurs and maxOccurs + values are rejected as well. + + + + SOAP encoding errors now report the affected type or failing operation in + the error message instead of the generic + Encoding: Violation of encoding rules message. + Code that compares the exact message may need to be updated. + + + + + + Sockets + + + socket_set_option with + SO_ATTACH_REUSEPORT_CBPF now requires an + int value and a + level of SOL_SOCKET. + Any other value type throws a TypeError + instead of being coerced, and any other level raises a warning and + returns &false;. + + + + socket_set_option with + SO_ATTACH_REUSEPORT_CBPF and a + value of 0 now detaches the + reuseport filter through SO_DETACH_REUSEPORT_BPF. + It previously used SO_DETACH_BPF, an alias of + SO_DETACH_FILTER, which left the reuseport program + attached. + + + + + + Sodium + + + The password-hashing functions sodium_crypto_pwhash, + sodium_crypto_pwhash_str, + sodium_crypto_pwhash_scryptsalsa208sha256 and + sodium_crypto_pwhash_scryptsalsa208sha256_str now + throw a ValueError instead of a + SodiumException when an argument is out of + range, such as an opslimit or + memlimit below the documented minimum. + SodiumException is still thrown for + internal libsodium failures. + + + + + + SPL + + + SplObjectStorage::getHash implementations may no + longer mutate any SplObjectStorage instance. + Attempting to do so now throws an Error. + + + + SplFileObject::next now advances the stream when + no prior SplFileObject::current call has cached a + line. + A subsequent SplFileObject::current call returns + the new line rather than the previous one. + + + + SplFileObject::fgets no longer caches the returned + line for subsequent SplFileObject::current calls. + SplFileObject::current now re-reads from the + current stream position instead of returning the line + SplFileObject::fgets just returned. + + + + SplFileObject::next past EOF no longer increments + SplFileObject::key without bound. + SplFileObject::seek past EOF now produces the same + SplFileObject::key value as + SplTempFileObject; the two previously returned + different values. + + + + DirectoryIterator::key now returns + intstring, and + DirectoryIterator::current returns + stringSplFileInfostatic. + + + + + + Sysvshm + + + shm_attach now raises a + ValueError when the + key argument is outside the platform's + key_t range instead of passing a truncated key to the + operating system. + + + + + + URI + + + Uri\WhatWg\Url::__construct now sets + softErrors to an empty array when URL processing + throws an exception, instead of preserving its value. + URL validation errors remain available in the + Uri\WhatWg\InvalidUrlException::$errors property. + + + + + + Zip + + + ZipArchive::extractTo now raises a + TypeError for the + files argument if one or more of the entries is not + a string. + + + + ZipArchive::addGlob and + ZipArchive::addPattern now raise a + TypeError when the + "remove_all_path" option is not of type + bool, or when the "comp_method", + "comp_flags", or "enc_method" + options are not of type int (numeric strings are coerced), + instead of emitting a warning. + + + + Serializing or unserializing a ZipArchive now + throws an Exception. + A subclass can override __serialize() and + __unserialize() to round-trip through + ZipArchive::closeString and + ZipArchive::openString. + + + + + + Zlib + + + deflate_init now raises a + TypeError when the value for option + "level", "memory", + "window", or "strategy" is not of + type int. + + + + inflate_init now raises a + TypeError when the value for option + "window" is not of type int. + + + + + + + + + + - New ValueError and TypeError exceptions + New errors for invalid arguments - - array_filter now raises a - ValueError when an invalid - mode argument value is passed. - + + The following functions now raise a + ValueError when an invalid flag or mode + value is passed: - - array_change_key_case now raises a - ValueError when an invalid - case argument value is passed. - + + array_filter (mode) + array_change_key_case (case) + pathinfo (flags) + scandir (sorting_order) + + - - getenv and putenv now raise a - ValueError when the first argument contains - NUL bytes. - + + The following functions now raise a + ValueError when the given argument contains + NUL bytes: - - dl now raises a - ValueError when the - extension_filename argument contains - NUL bytes. - + + getenv and putenv (first argument) + dl (extension_filename) + openlog (prefix) + parse_str (string) + proc_open (cwd) + + - - openlog now raises a - ValueError when the - prefix argument contains NUL - bytes. - + + The following functions now raise a + ValueError for out-of-range values instead + of silently clamping them or allowing them to overflow: + + + + number_format, when decimals + is outside the integer range. + + + sleep, when seconds is + greater than UINT_MAX, or + UINT_MAX / 1000 on Windows. + + + usleep, when microseconds is + greater than UINT_MAX. + + + - parse_str now raises a + linkinfo now raises a ValueError when the - string argument contains NUL - bytes. + path argument is empty. @@ -117,52 +172,6 @@ ArgumentCountError. - - linkinfo now raises a - ValueError when the - path argument is empty. - - - - pathinfo now raises a - ValueError when an invalid - flags argument value is passed. - - - - scandir now raises a - ValueError when an invalid - sorting_order argument value is passed. - - - - number_format now raises a - ValueError when - decimals is outside the integer range instead of - silently clamping very large positive values. - - - - sleep now raises a - ValueError when - seconds is greater than the platform limit - (UINT_MAX seconds, or UINT_MAX / 1000 - seconds on Windows) instead of allowing the value to overflow. - - - - usleep now raises a - ValueError when - microseconds is greater than - UINT_MAX instead of allowing the value to overflow. - - - - proc_open now raises a - ValueError when the - cwd argument contains NUL bytes. - - The following functions now raise a ValueError when the @@ -205,7 +214,7 @@ - Endianness modifiers in unpack() format names + Endianness modifiers in <function>unpack</function> format names unpack now reads a < or @@ -219,9 +228,23 @@ format code accepts no endianness modifier. A name starting with these characters is unaffected when a repeater precedes it, as in "s1<value". + See also the + new + endianness modifiers. + + + 1] +// Prior to PHP 8.6.0: [" 1] +]]> + + + @@ -271,14 +294,9 @@ Array access on Dom\DtdNamedNodeMap objects now returns &null; for negative integer indexes instead of returning the first - node. - - - - Array access on Dom\DtdNamedNodeMap objects now - raises a ValueError when the integer index - is greater than PHP_INT_MAX instead of overflowing - to a smaller index. + node, and raises a ValueError when the + integer index is greater than PHP_INT_MAX instead of + overflowing to a smaller index. @@ -347,9 +365,9 @@ - gmp_powm modulo-by-zero now raises a - DivisionByZeroError whose message includes - the function name and argument index (modulus). + The message of the DivisionByZeroError + raised by gmp_powm on modulo by zero now includes the + function name and argument index (modulus). @@ -420,7 +438,7 @@ Collator::sort, collator_sort, Collator::asort, and - collator_asort now report UTF-8/UTF-16 conversion + collator_asort now report UTF-8/UTF-16 conversion failures during comparison through the intl error mechanism and return &false;. With intl.use_exceptions @@ -463,7 +481,8 @@ preg_grep now returns &false; instead of a partial - array when a PCRE execution error occurs (e.g. malformed UTF-8 input with + array when a PCRE execution error occurs (e.g. malformed + UTF-8 input with the u modifier). This is consistent with the other preg_* functions. @@ -474,10 +493,10 @@ PGSQL - pg_fetch_object now reports the - ValueError for a non-empty - constructor_args on a class without a constructor - on the constructor_args argument instead of + When pg_fetch_object is given a non-empty + constructor_args for a class without a constructor, + the ValueError now refers to the + constructor_args argument instead of class. Errors raised when the requested class is not instantiable (abstract, interface, enum) now surface before the row is fetched. @@ -501,12 +520,8 @@ BadMethodCallException for attempts to create the reserved magic ".phar" directory through that form. - - - - Phar::addEmptyDir now treats non-magic names that - merely share the ".phar" prefix as ordinary - directories. + Non-magic names that merely share the ".phar" prefix + are now treated as ordinary directories. @@ -596,7 +611,7 @@ session.cookie_samesite is now "Lax" (was unset). Session cookies are no longer sent on cross-site requests other than - top-level navigations using safe HTTP methods. + top-level navigations using safe HTTP methods. Applications that depend on session cookies being sent on cross-site POST submissions must explicitly set this to "None" (and also set @@ -609,9 +624,9 @@ SessionHandler::validateId has been added and delegates to the configured save handler. - A subclass that declares validateId() without a return - type now emits a deprecation notice for the tentative bool - return type. + A subclass that declares SessionHandler::validateId + without a return type now emits a deprecation notice for the tentative + bool return type. A subclass that overrides SessionHandler::open without calling parent::open() keeps its previous behavior and emits a warning when an ID is validated. @@ -665,7 +680,7 @@ - WSDL/XML Schema parsing now rejects out-of-range integer values for + WSDL/XML Schema parsing now rejects out-of-range integer values for occurrence constraints and integer restriction facets. Negative minOccurs and maxOccurs values are rejected as well. @@ -749,9 +764,9 @@ - SplFileObject::next past EOF no longer increments + SplFileObject::next past EOF no longer increments SplFileObject::key without bound. - SplFileObject::seek past EOF now produces the same + SplFileObject::seek past EOF now produces the same SplFileObject::key value as SplTempFileObject; the two previously returned different values. @@ -816,8 +831,9 @@ Serializing or unserializing a ZipArchive now throws an Exception. - A subclass can override __serialize() and - __unserialize() to round-trip through + A subclass can override + __serialize() and + __unserialize() to round-trip through ZipArchive::closeString and ZipArchive::openString. From b0e11b731e0d2a729c3fd5e29545fad74e6bf40b Mon Sep 17 00:00:00 2001 From: Jordi Kroon Date: Wed, 30 Sep 2026 20:20:21 +0200 Subject: [PATCH 11/17] Document other changes --- appendices/migration86/other-changes.xml | 596 +++++++++++++++++++++++ 1 file changed, 596 insertions(+) diff --git a/appendices/migration86/other-changes.xml b/appendices/migration86/other-changes.xml index 42be132a941a..64cf64d92766 100644 --- a/appendices/migration86/other-changes.xml +++ b/appendices/migration86/other-changes.xml @@ -2,6 +2,602 @@ Other Changes + + Core changes + + + Core + + + In case of a hard OOM (out of memory) condition, PHP + now calls abort() instead of exit(1), + changing the exit code to 134 and possibly creating a core dump. + + + + The PHP_OS_FAMILY constant has an + AIX value for when running on AIX or IBM i via PASE. + + + + + + + + Changes in SAPI Modules + + + CLI + + + The built-in development + server now accepts requests using the HTTP QUERY + method instead of returning 501 Not Implemented. + + + + The built-in development + server no longer reflects the Host header from + requests. + + + + + + + + Changed Functions + + + Core + + + header_register_callback now declares + true as its return type. + It has not been able to return &false; since PHP 8.0.0, when passing an + invalid callback started throwing a + TypeError instead. + + + + register_tick_function now declares + true as its return type. + It has always returned &true; on success; an invalid callback throws a + TypeError during argument parsing before + the function body is reached. + + + + ini_get_all now includes a + "builtin_default_value" element for each directive + when details is &true;. + It holds the built-in default value of the directive (or &null; if it + has none), independent of values set in &php.ini;, on the command line, + or at runtime. + + + + fclose, file_put_contents and + copy now return &false; when flushing or closing the + stream fails. + Previously such failures were silently ignored. + + + + + + Date + + + The following methods now have tentative static return + types: + + + DateTime::createFromInterface + DateTimeImmutable::__set_state + DateTimeImmutable::modify + DateTimeImmutable::add + DateTimeImmutable::sub + DateTimeImmutable::setTimezone + DateTimeImmutable::setTime + DateTimeImmutable::setDate + DateTimeImmutable::setISODate + DateTimeImmutable::setTimestamp + DateTimeImmutable::createFromInterface + DateTimeZone::__set_state + DateInterval::__set_state + DatePeriod::__set_state + + + + + + + Filter + + + The return type of filter_var_array has been + narrowed from + arrayfalsenull + to arrayfalse. + The function always establishes an array before filtering, so &null; was + never returned. + filter_input_array is unaffected: it still returns + &null; when the requested superglobal does not exist. + + + + + + LDAP + + + The return type of ldap_free_result has been + narrowed from bool to true. + The function already always returned &true;. + + + + + + MySQLi + + + The return structure of mysqli_get_charset no longer + contains the undocumented "comment" element. + The value of "charsetnr" is now set to a constant + 0 as this number was an implementation detail that + should not have been exposed to the public. + + + + + + OpenSSL + + + The output of openssl_x509_parse now contains a + "criticalExtensions" entry listing all critical + certificate extensions. + + + + openssl_sign and openssl_verify + now have an additional optional salt_length + argument that allows controlling the RSA-PSS salt length when + OPENSSL_PKCS1_PSS_PADDING is used. + It accepts an explicit length or one of the new + OPENSSL_RSA_PSS_SALTLEN_* + constants. + + + + + + PDO_DBLIB + + + When using persistent connections, there is now a liveness check in the + constructor. + + + + + + Phar + + + Phar::mungServer now supports reference values. + + + + + + Readline + + + readline_completion_function now declares + true as its return type. + The function assigns a static callback and then tests whether the + assignment landed, which is a tautology; an invalid callback throws a + TypeError during argument parsing before + the function body is reached. + + + + + + Reflection + + + The outputs of + ReflectionClassConstant::__toString and + ReflectionConstant::__toString for constants + with boolean values have been changed to use true and + false rather than 1 and an empty + string. + This also affects other ways of printing class constants, e.g. + ReflectionClass::__toString. + + + + + + Sockets + + + socket_addrinfo_lookup now has an additional + optional error_code argument that, when not + &null;, receives the error code on failure (one of the + EAI_* constants). + + + + The return type of socket_cmsg_space has been + narrowed from intnull + to int. + Every failure path has thrown a + ValueError since PHP 8.0, so &null; was + never returned. + + + + + + + Zip + + + The return type of zip_entry_close has been narrowed + from bool to true. + The function already always returned &true;. + + + + + + + + Other Changes to Extensions + + + Fileinfo + + + Upgraded to file 5.48. + Custom compiled magic databases from older file versions must be + regenerated. + + + + + + Hash + + + The bundled version of xxHash was upgraded to 0.8.2. + + + + + + MySQLi + + + Added the new constant MYSQLI_OPT_COMPRESS. + + + + + + Opcache + + + JIT is now supported for ZTS builds + on Apple Silicon. + + + + + + + + Changes to INI File Handling + + + Core + + + The error_include_args + INI option has been added to make the display of function arguments + consistent in errors; it is off by default. + Previously, whether a function showed a parameter in the error was up to + each call to the internal error function. + Now, all parameters as they were actually passed to the function will be + displayed. + This uses the same infrastructure as stack traces, so sensitive + parameters will not be displayed, and strings will be truncated + according to + zend.exception_string_param_max_len. + + + + + + + MBString + + + The mbstring.detect_order + INI directive now updates the internal detection order when changed at + runtime via ini_set. + Previously, runtime changes using ini_set did not + take effect for mb_detect_order. + Setting the directive to &null; or an empty string at runtime now leaves + the previously configured detection order unchanged. + + + + + + MySQLi + + + mysqli.default_port now + checks the validity of the value, which should be between + 0 and 65535 inclusive. + + + + + + Opcache + + + opcache.jit_debug accepts a + new flag: ZEND_JIT_DEBUG_TRACE_EXIT_INFO_SRC. + When used along with ZEND_JIT_DEBUG_TRACE_EXIT_INFO, + the source of exit points is printed in the exit info output, in debug + builds. + + + + + + + + Performance + + + Core + + + printf using only %s and + %d will be compiled into the equivalent string + interpolation, avoiding the overhead of a function call and repeatedly + parsing the format string. + + + + Arguments are now passed more efficiently to known constructors (e.g. + when using new self()). + + + + array_map using a + first-class + callable or partial function application callback will be compiled + into the equivalent foreach loop, avoiding the + creation of intermediate Closures, the overhead of + calling userland callbacks from internal functions and providing for + better insight for the JIT. + + + + The performance of the TAILCALL VM has been improved. + + + + The TAILCALL VM is now enabled on Windows when compiling with + Clang 19 or later on x86_64. + + + + The performance of ZTS builds has been improved. + + + + Added a stateless closure cache. + + + + + Deeply recursive code that causes the VM to allocate new stack pages + should now be faster. + + + + Improved performance of addcslashes when generating + octal escapes. + + + + Improved performance of sorting single-element arrays. + + + + Improved performance of array_fill_keys. + + + + Improved performance of array_intersect. + + + + Improved performance of array_map with multiple + arrays passed. + + + + Improved performance of array_sum and + array_product for integer-only arrays. + + + + Improved performance of array_unshift. + + + + Improved performance of array_walk. + + + + Improved performance of intval('+0b...', 2) and + intval('0b...', 2). + + + + Improved performance of pathinfo when requesting a + single component. + + + + Improved performance of str_split. + + + + Improved performance of str_pad. + + + + Improved performance of str_repeat when the + multiplier is 1. + + + + + + DOM + + + Made DOMText::splitText and + Dom\Text::splitText faster and consume less + memory. + + + + + + GD + + + imagebmp, imagewbmp, + imagegd, and imagegd2 now + buffer output when writing to PHP streams, significantly improving + performance when writing images to files. + + + + Improved performance of imagegrabscreen and + imagegrabwindow on Windows. + + + + + + Intl + + + Improved performance of + IntlCalendar::getAvailableLocales and + IntlDateFormatter::localtime/datefmt_localtime + by pre-allocating their returned arrays. + + + + Improved performance of transliterator_list_ids and + resourcebundle_locales by pre-allocating their + returned arrays. + + + + Optimized callback invocation in + IntlChar::enumCharTypes. + + + + + + JSON + + + Improved performance of encoding arrays and objects. + + + + Improved performance of indentation generation in + json_encode when using + JSON_PRETTY_PRINT. + + + + + + MBString + + + Improved performance of mb_str_pad. + + + + + + Phar + + + Reduced temporary allocations when iterating Phar directories. + + + + + + URI + + + Improved performance of Uri\WhatWg\Url::parse + when collecting validation errors by pre-allocating the error array. + + + + Reduced allocations when reading IPv6/IPvFuture hosts and paths with + Uri\Rfc3986\Uri. + + + + Improved performance and memory consumption when using normalizing + (non-raw) getters on already-normalized URIs with + Uri\Rfc3986\Uri. + + + + + + Zip + + + Improved performance of ZipArchive::addGlob and + ZipArchive::addPattern by pre-allocating their + returned arrays. + + + + Avoid string copies in ZipArchive::addFromString. + + + + + + - URI Uri\Rfc3986\UriBuilder Uri\WhatWg\UrlBuilder - Uri\WhatWg\UrlPercentEncodingMode + Uri\WhatWg\UrlPercentEncodingMode diff --git a/appendices/migration86/new-features.xml b/appendices/migration86/new-features.xml index 0f765fbb7148..e30ad8268b78 100644 --- a/appendices/migration86/new-features.xml +++ b/appendices/migration86/new-features.xml @@ -505,7 +505,7 @@ var_dump(unpack('s>value', "\xff\xfe")); // ["value" => int(-2)] Added a new stream errors API, consisting of: - The StreamError and StreamException classes + The StreamError and StreamException classes The StreamErrorStore, StreamErrorMode, and StreamErrorCode enums The stream_last_errors and stream_clear_errors functions diff --git a/appendices/migration86/new-functions.xml b/appendices/migration86/new-functions.xml index cb54e72be10a..afb6f30c41ad 100644 --- a/appendices/migration86/new-functions.xml +++ b/appendices/migration86/new-functions.xml @@ -187,7 +187,6 @@ - URI diff --git a/appendices/migration86/windows-support.xml b/appendices/migration86/windows-support.xml index 1ec36100abd5..ee6aea1774bf 100644 --- a/appendices/migration86/windows-support.xml +++ b/appendices/migration86/windows-support.xml @@ -19,7 +19,7 @@ to version 2.15.3. As a result, DOMDocument::$documentURI for documents loaded from a local file now contains a native filesystem path instead of - a file URI. + a file URI. From 8b2d215f8a3dc56b1f402e093f128d40293c7cdd Mon Sep 17 00:00:00 2001 From: Jordi Kroon Date: Tue, 6 Oct 2026 14:24:12 +0200 Subject: [PATCH 14/17] Apply batched suggestions from code review Co-authored-by: Louis-Arnaud --- appendices/migration86/incompatible.xml | 4 +++- appendices/migration86/new-features.xml | 8 +++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/appendices/migration86/incompatible.xml b/appendices/migration86/incompatible.xml index b96c8dce5ac4..f08805f9448e 100644 --- a/appendices/migration86/incompatible.xml +++ b/appendices/migration86/incompatible.xml @@ -27,7 +27,9 @@ __isset() has materialized the property by writing into the property table. The freshly-written value is returned directly. - isset is unaffected. + isset applied directly to the property is unaffected; + nested forms such as isset($o->p['k']) follow the same + path as ??. diff --git a/appendices/migration86/new-features.xml b/appendices/migration86/new-features.xml index e30ad8268b78..ab2bdb8034bd 100644 --- a/appendices/migration86/new-features.xml +++ b/appendices/migration86/new-features.xml @@ -208,8 +208,10 @@ var_dump(CONFIG->debug); // bool(true) pack and unpack now accept the < (little-endian) and > - (big-endian) modifiers after the signed and unsigned integer format codes, - and after the float and double format codes. + (big-endian) modifiers after the s, S, + l, L, q and + Q integer format codes, and after the + f and d float and double format codes. @@ -568,7 +570,7 @@ var_dump(unpack('s>value', "\xff\xfe")); // ["value" => int(-2)] Added the "write_seek_mode" filter parameter for the - bz2, iconv, zlib, and string stream + bz2, iconv, zlib, and convert stream filters. This parameter must be set via an associative array where the key is "write_seek_mode" and the value is one of the following From 2335a03a991268981a5dbd27c1e5618a010fafaa Mon Sep 17 00:00:00 2001 From: Jordi Kroon Date: Thu, 8 Oct 2026 19:59:06 +0200 Subject: [PATCH 15/17] Remove EOF functions from migration guide --- appendices/migration86/constants.xml | 8 -------- appendices/migration86/new-functions.xml | 16 ---------------- 2 files changed, 24 deletions(-) diff --git a/appendices/migration86/constants.xml b/appendices/migration86/constants.xml index cdbc9dbb7f6c..c3d4ced715a0 100644 --- a/appendices/migration86/constants.xml +++ b/appendices/migration86/constants.xml @@ -149,14 +149,6 @@ SODIUM_CRYPTO_IPCRYPT_NDX_OUTPUTBYTES SODIUM_CRYPTO_IPCRYPT_PFX_KEYBYTES SODIUM_CRYPTO_IPCRYPT_PFX_BYTES - SODIUM_CRYPTO_XOF_SHAKE128_BLOCKBYTES - SODIUM_CRYPTO_XOF_SHAKE128_STATEBYTES - SODIUM_CRYPTO_XOF_SHAKE256_BLOCKBYTES - SODIUM_CRYPTO_XOF_SHAKE256_STATEBYTES - SODIUM_CRYPTO_XOF_TURBOSHAKE128_BLOCKBYTES - SODIUM_CRYPTO_XOF_TURBOSHAKE128_STATEBYTES - SODIUM_CRYPTO_XOF_TURBOSHAKE256_BLOCKBYTES - SODIUM_CRYPTO_XOF_TURBOSHAKE256_STATEBYTES SODIUM_CRYPTO_KEM_PUBLICKEYBYTES (libsodium >= 1.0.22) SODIUM_CRYPTO_KEM_SECRETKEYBYTES (libsodium >= 1.0.22) SODIUM_CRYPTO_KEM_CIPHERTEXTBYTES (libsodium >= 1.0.22) diff --git a/appendices/migration86/new-functions.xml b/appendices/migration86/new-functions.xml index afb6f30c41ad..a20e69c629a1 100644 --- a/appendices/migration86/new-functions.xml +++ b/appendices/migration86/new-functions.xml @@ -138,22 +138,6 @@ sodium_crypto_ipcrypt_pfx_decrypt sodium_bin2ip sodium_ip2bin - sodium_crypto_xof_shake128 - sodium_crypto_xof_shake128_init - sodium_crypto_xof_shake128_update - sodium_crypto_xof_shake128_squeeze - sodium_crypto_xof_shake256 - sodium_crypto_xof_shake256_init - sodium_crypto_xof_shake256_update - sodium_crypto_xof_shake256_squeeze - sodium_crypto_xof_turboshake128 - sodium_crypto_xof_turboshake128_init - sodium_crypto_xof_turboshake128_update - sodium_crypto_xof_turboshake128_squeeze - sodium_crypto_xof_turboshake256 - sodium_crypto_xof_turboshake256_init - sodium_crypto_xof_turboshake256_update - sodium_crypto_xof_turboshake256_squeeze From 26eb28e19e5148926942c9415729fe59cbc28377 Mon Sep 17 00:00:00 2001 From: Jordi Kroon Date: Tue, 13 Oct 2026 18:42:40 +0200 Subject: [PATCH 16/17] Fix incorrect entity ref --- appendices/migration86/deprecated.xml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/appendices/migration86/deprecated.xml b/appendices/migration86/deprecated.xml index 2cc561a6530b..2ce6ce2a5322 100644 --- a/appendices/migration86/deprecated.xml +++ b/appendices/migration86/deprecated.xml @@ -28,9 +28,8 @@ - Using the return statement inside a - finally block is now - deprecated, and emits a compile-time deprecation notice. + Using the return statement inside a &finally; block + is now deprecated, and emits a compile-time deprecation notice. Such a return silently discards an exception thrown by, or overwrites the value returned from, the associated try or catch block, so failures From ecc7bdcf62ef6b02c0961b55122bbb4163a188e6 Mon Sep 17 00:00:00 2001 From: Jordi Kroon Date: Tue, 13 Oct 2026 18:54:23 +0200 Subject: [PATCH 17/17] Document php-src#c01c9d009c1db68a87dabd45b128f544913a63f2 --- appendices/migration86/incompatible.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/appendices/migration86/incompatible.xml b/appendices/migration86/incompatible.xml index f08805f9448e..bb64e35ce4cf 100644 --- a/appendices/migration86/incompatible.xml +++ b/appendices/migration86/incompatible.xml @@ -807,6 +807,15 @@ var_dump(unpack('sUri\WhatWg\InvalidUrlException::$errors property. + + Uri\WhatWg\Url::__construct, + Uri\WhatWg\Url::parse, the + Uri\WhatWg\Url::with*() methods, and + Uri\WhatWg\UrlBuilder::build now report + validation errors in the order in which they are detected. + This reverses the order of multiple errors compared to PHP 8.5. + +