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..c3d4ced715a0
--- /dev/null
+++ b/appendices/migration86/constants.xml
@@ -0,0 +1,187 @@
+
+
+ New Global Constants
+
+
+ Core
+
+
+
+ ARRAY_FILTER_USE_VALUE
+
+
+ STREAM_CRYPTO_STATUS_NONE
+
+
+ STREAM_CRYPTO_STATUS_WANT_READ
+
+
+ STREAM_CRYPTO_STATUS_WANT_WRITE
+
+
+
+
+
+ cURL
+
+
+
+ CURLINFO_SIZE_DELIVERED (libcurl >= 8.20.0)
+
+
+ CURLOPT_SEEKFUNCTION
+
+
+ CURL_SEEKFUNC_OK
+
+
+ CURL_SEEKFUNC_FAIL
+
+
+ CURL_SEEKFUNC_CANTSEEK
+
+
+ CURL_READFUNC_ABORT
+
+
+
+
+
+ MySQLi
+
+
+
+ MYSQLI_OPT_COMPRESS
+
+
+
+
+
+ OpenSSL
+
+
+ OPENSSL_RSA_PSS_SALTLEN_DIGEST
+ OPENSSL_RSA_PSS_SALTLEN_AUTO
+ OPENSSL_RSA_PSS_SALTLEN_MAX
+
+
+
+
+ Sockets
+
+
+
+ TCP_USER_TIMEOUT (Linux only)
+
+
+ AF_UNSPEC
+
+
+ EAI_BADFLAGS
+
+
+ EAI_NONAME
+
+
+ EAI_AGAIN
+
+
+ EAI_FAIL
+
+
+ EAI_NODATA
+
+
+ EAI_FAMILY
+
+
+ EAI_SOCKTYPE
+
+
+ EAI_SERVICE
+
+
+ EAI_ADDRFAMILY
+
+
+ EAI_SYSTEM
+
+
+ EAI_OVERFLOW
+
+
+ EAI_INPROGRESS
+
+
+ EAI_CANCELED
+
+
+ EAI_NOTCANCELED
+
+
+ EAI_ALLDONE
+
+
+ EAI_INTR
+
+
+ EAI_IDN_ENCODE
+
+
+ SO_DETACH_REUSEPORT_BPF (Linux only)
+
+
+
+
+
+ Sodium
+
+
+ SODIUM_CRYPTO_IPCRYPT_BYTES
+ SODIUM_CRYPTO_IPCRYPT_KEYBYTES
+ SODIUM_CRYPTO_IPCRYPT_ND_KEYBYTES
+ SODIUM_CRYPTO_IPCRYPT_ND_TWEAKBYTES
+ SODIUM_CRYPTO_IPCRYPT_ND_INPUTBYTES
+ SODIUM_CRYPTO_IPCRYPT_ND_OUTPUTBYTES
+ SODIUM_CRYPTO_IPCRYPT_NDX_KEYBYTES
+ SODIUM_CRYPTO_IPCRYPT_NDX_TWEAKBYTES
+ SODIUM_CRYPTO_IPCRYPT_NDX_INPUTBYTES
+ SODIUM_CRYPTO_IPCRYPT_NDX_OUTPUTBYTES
+ SODIUM_CRYPTO_IPCRYPT_PFX_KEYBYTES
+ SODIUM_CRYPTO_IPCRYPT_PFX_BYTES
+ SODIUM_CRYPTO_KEM_PUBLICKEYBYTES (libsodium >= 1.0.22)
+ SODIUM_CRYPTO_KEM_SECRETKEYBYTES (libsodium >= 1.0.22)
+ SODIUM_CRYPTO_KEM_CIPHERTEXTBYTES (libsodium >= 1.0.22)
+ SODIUM_CRYPTO_KEM_SHAREDSECRETBYTES (libsodium >= 1.0.22)
+ SODIUM_CRYPTO_KEM_SEEDBYTES (libsodium >= 1.0.22)
+ SODIUM_CRYPTO_KEM_KEYPAIRBYTES (libsodium >= 1.0.22)
+ SODIUM_CRYPTO_KEM_MLKEM768_PUBLICKEYBYTES (libsodium >= 1.0.22)
+ SODIUM_CRYPTO_KEM_MLKEM768_SECRETKEYBYTES (libsodium >= 1.0.22)
+ SODIUM_CRYPTO_KEM_MLKEM768_CIPHERTEXTBYTES (libsodium >= 1.0.22)
+ SODIUM_CRYPTO_KEM_MLKEM768_SHAREDSECRETBYTES (libsodium >= 1.0.22)
+ SODIUM_CRYPTO_KEM_MLKEM768_SEEDBYTES (libsodium >= 1.0.22)
+ SODIUM_CRYPTO_KEM_MLKEM768_KEYPAIRBYTES (libsodium >= 1.0.22)
+
+
+
+
+
diff --git a/appendices/migration86/deprecated.xml b/appendices/migration86/deprecated.xml
new file mode 100644
index 000000000000..2ce6ce2a5322
--- /dev/null
+++ b/appendices/migration86/deprecated.xml
@@ -0,0 +1,612 @@
+
+
+ Deprecated Features
+
+
+ PHP Core
+
+
+ Using "namespace" as a class constant name
+
+
+
+ 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.
+
+
+
+
+
+ Returning from a finally block
+
+
+
+ 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()
+
+
+ Declaring a return type of
+ arraynull for
+ __debugInfo() is now
+ deprecated.
+ 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.
+
+
+
+
+
+ Returning values from __construct() and __destruct()
+
+
+
+ Returning a value from
+ __construct() or
+ __destruct() is now
+ 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.
+
+
+
+ For the same reason, using yield to make
+ __construct() or
+ __destruct() a
+ generator is now deprecated.
+
+
+
+
+
+ Naming a function readonly
+
+
+
+ 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.
+
+
+
+
+
+ Third argument to define()
+
+
+
+ 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.
+
+
+
+
+
+ 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 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 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 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 as the array argument to
+ array_walk or
+ array_walk_recursive is now deprecated.
+ 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.
+ 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()
+
+
+
+
+
+
+ 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:
+
+
+ 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.
+ 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 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
+ Collator::asort
+ Collator::sortWithSortKeys
+
+
+
+
+
+
+
+
+ Bzip2
+
+
+ Passing an object as the parameters of the
+ bzip2.compress and
+ 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.
+
+
+
+
+
+
+ GMP
+
+
+ The shift (<<, >>) and
+ exponentiation (**) operators on
+ 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.
+
+
+
+
+
+ MBString
+
+
+ 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 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.
+
+
+
+
+
+
+ MySQLi
+
+
+ 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 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.
+
+
+
+
+
+
+ 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.
+ 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.
+
+
+
+
+ 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.
+
+
+
+
+
+
+ Session
+
+
+ Passing an object that does not implement both the
+ SessionIdInterface::create_sid and
+ SessionUpdateTimestampHandlerInterface::validateId
+ methods to session_set_save_handler is now
+ 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.
+
+
+
+
+ Accordingly, a deprecation notice is now emitted when a class implements
+ SessionHandlerInterface without defining
+ the SessionIdInterface::create_sid or
+ SessionUpdateTimestampHandlerInterface::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.
+
+
+
+
+
+ SPL
+
+
+ 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.
+ 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.
+
+
+
+ ArrayIterator::getFlags
+ ArrayIterator::setFlags
+ ArrayIterator::asort
+ ArrayIterator::ksort
+ ArrayIterator::uasort
+ ArrayIterator::uksort
+ ArrayIterator::natsort
+ ArrayIterator::natcasesort
+ ArrayIterator::unserialize
+ ArrayIterator::serialize
+
+
+
+
+ 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.
+
+
+
+ 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, 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 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.
+
+
+
+
+
+
+
diff --git a/appendices/migration86/incompatible.xml b/appendices/migration86/incompatible.xml
new file mode 100644
index 000000000000..bb64e35ce4cf
--- /dev/null
+++ b/appendices/migration86/incompatible.xml
@@ -0,0 +1,893 @@
+
+
+ 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 applied directly to the property is unaffected;
+ nested forms such as isset($o->p['k']) follow the same
+ path as ??.
+
+
+
+
+$name = 'from __isset()';
+ return true;
+ }
+
+ public function __get(string $name): string
+ {
+ return 'from __get()';
+ }
+}
+
+$example = new Example();
+var_dump($example->foo ?? 'default');
+// As of PHP 8.6.0: string(14) "from __isset()"
+// Prior to PHP 8.6.0: string(12) "from __get()"
+]]>
+
+
+
+
+
+
+ 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 errors for invalid arguments
+
+
+ The following functions now raise a
+ ValueError when an invalid flag or mode
+ value is passed:
+
+
+ array_filter (mode)
+ array_change_key_case (case)
+ pathinfo (flags)
+ scandir (sorting_order)
+
+
+
+
+ The following functions now raise a
+ ValueError when the given argument contains
+ NUL bytes:
+
+
+ getenv and putenv (first argument)
+ dl (extension_filename)
+ openlog (prefix)
+ parse_str (string)
+ proc_open (cwd)
+
+
+
+
+ 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.
+
+
+
+
+
+ linkinfo now raises a
+ ValueError when the
+ path argument is empty.
+
+
+
+ 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.
+
+
+
+ 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".
+ See also the
+ new
+ endianness modifiers.
+
+
+
+
+
+ 1]
+// Prior to PHP 8.6.0: [" 1]
+]]>
+
+
+
+
+
+
+
+
+ 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, and 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.
+
+
+
+ The message of the DivisionByZeroError
+ raised by gmp_powm on modulo by zero now 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
+
+
+ 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.
+
+
+
+
+
+ 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.
+ Non-magic names that merely share the ".phar" prefix
+ are now treated 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 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.
+
+
+
+
+
+ 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
+ intvalue 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.
+
+
+
+ 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.
+
+
+
+
+
+ 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.
+
+
+
+
+
+
diff --git a/appendices/migration86/new-classes.xml b/appendices/migration86/new-classes.xml
new file mode 100644
index 000000000000..6467a582d4b2
--- /dev/null
+++ b/appendices/migration86/new-classes.xml
@@ -0,0 +1,105 @@
+
+
+ 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
+
+
+
+
+
+
+
diff --git a/appendices/migration86/new-features.xml b/appendices/migration86/new-features.xml
new file mode 100644
index 000000000000..ab2bdb8034bd
--- /dev/null
+++ b/appendices/migration86/new-features.xml
@@ -0,0 +1,635 @@
+
+
+ New Features
+
+
+ PHP Core
+
+
+ Default values for readonly properties
+
+
+ Readonly
+ properties may now declare default values.
+
+
+
+
+
+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.
+ Previously, this resulted in a fatal error.
+
+
+
+
+
+ $this->name, 'symbol' => $this->value];
+ }
+}
+
+var_dump(Suit::Hearts);
+]]>
+
+ &example.outputs;
+
+
+ string(6) "Hearts"
+ ["symbol"]=>
+ string(1) "H"
+}
+]]>
+
+
+
+
+
+
+ #[\Override] for class constants
+
+
+ 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.
+
+
+
+
+
+
+
+
+
+
+
+
+ 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.
+
+
+
+
+
+debug = true;
+
+var_dump(CONFIG->debug); // bool(true)
+]]>
+
+
+
+
+
+
+ Endianness modifiers for pack() and unpack()
+
+
+ pack and unpack now accept the
+ < (little-endian) and >
+ (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.
+
+
+
+
+
+
+', 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)]
+]]>
+
+
+
+
+
+
+
+
+ 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 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
+ 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
+ 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.
+ This allows saving and restoring client sessions across requests,
+ implementing custom server-side session storage, and controlling session
+ 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
+ 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:
+
+ 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, 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
+ 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 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
+ strings:
+
+ "preserve"
+ "reset"
+ "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.
+
+
+
+
+
+
+
diff --git a/appendices/migration86/new-functions.xml b/appendices/migration86/new-functions.xml
new file mode 100644
index 000000000000..a20e69c629a1
--- /dev/null
+++ b/appendices/migration86/new-functions.xml
@@ -0,0 +1,230 @@
+
+
+ New Functions
+
+
+ Core
+
+
+
+
+ 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
+
+
+
+ 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
+
+
+
+
+
+
diff --git a/appendices/migration86/other-changes.xml b/appendices/migration86/other-changes.xml
new file mode 100644
index 000000000000..3cb6af61bd59
--- /dev/null
+++ b/appendices/migration86/other-changes.xml
@@ -0,0 +1,585 @@
+
+
+ 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
+ PDO::__construct.
+
+
+
+
+
+ Phar
+
+
+ Phar::mungServer now supports reference values.
+
+
+
+
+
+ Readline
+
+
+ readline_completion_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.
+
+
+
+
+
+ Reflection
+
+
+ The outputs of
+ ReflectionClassConstant::__toString and
+ ReflectionConstant::__toString now print
+ bool constant values as 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.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,
+ and it 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 sorting single-element arrays.
+
+
+
+ Improved performance of the following functions:
+
+
+ addcslashes, when generating octal escapes
+ array_fill_keys
+ array_intersect
+ array_map, with multiple arrays passed
+ array_product and array_sum, for integer-only arrays
+ array_unshift
+ array_walk
+ intval, for intval('0b...', 2) and intval('+0b...', 2)
+ pathinfo, when requesting a single component
+ str_pad
+ str_repeat, when the multiplier is 1
+ str_split
+
+
+
+
+
+
+ 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.
+
+
+
+
+
+
+
+
diff --git a/appendices/migration86/windows-support.xml b/appendices/migration86/windows-support.xml
new file mode 100644
index 000000000000..ee6aea1774bf
--- /dev/null
+++ b/appendices/migration86/windows-support.xml
@@ -0,0 +1,57 @@
+
+
+ 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.
+
+
+
+
+
+
diff --git a/manual.xml b/manual.xml
index f393b9f67120..d9302073d28d 100644
--- a/manual.xml
+++ b/manual.xml
@@ -412,6 +412,7 @@