xref: /PHP-8.4/UPGRADING (revision efe4fc9f)
1PHP 8.4 UPGRADE NOTES
2
31. Backward Incompatible Changes
42. New Features
53. Changes in SAPI modules
64. Deprecated Functionality
75. Changed Functions
86. New Functions
97. New Classes and Interfaces
108. Removed Extensions and SAPIs
119. Other Changes to Extensions
1210. New Global Constants
1311. Changes to INI File Handling
1412. Windows Support
1513. Other Changes
1614. Performance Improvements
17
18========================================
191. Backward Incompatible Changes
20========================================
21
22- Core:
23  . The type of PHP_DEBUG and PHP_ZTS constants changed to bool.
24  . The name of uploaded files and files created by the tempnam() function are
25    now 13 bytes longer. Total length is platform-dependent.
26  . Encountering recursion during comparison now results in a Error exception,
27    rather than a fatal error.
28  . Indirect modification of readonly properties within __clone() is no longer
29    allowed, e.g. $ref = &$this->readonly. This was already forbidden for
30    readonly initialization, and was an oversight in the "readonly
31    reinitialization during cloning" implementation.
32  . The exit (and die) language constructs now behave more like a function.
33    They can be passed like callables, are affected by the strict_types
34    declare statement, and now perform the usual type coercions instead of
35    casting any non-integer value to a string.
36    As such, passing invalid types to exit/die may now result in a TypeError
37    being thrown.
38    RFC: https://wiki.php.net/rfc/exit-as-function
39  . The E_STRICT constant was deprecated and its corresponding error level was
40    removed.
41    RFC: https://wiki.php.net/rfc/deprecations_php_8_4#remove_e_strict_error_level_and_deprecate_e_strict_constant
42
43- Extension Class constants are now typed:
44  . Date
45  . Intl
46  . PDO
47  . Reflection
48  . SPL
49  . Sqlite
50  . XMLReader
51
52- Resource to Object conversions:
53  Return value checks using is_resource() should be replaced with checks
54  for `false`, unless specified otherwise.
55  . DBA:
56    . dba_open() and dba_popen() will now return Dba\Connection
57  . ODBC:
58    . odbc_connect() and odbc_pconnect() will now return Odbc\Connection
59    . odbc_prepare(), odbc_exec(), and various other functions will now return
60      Odbc\Result
61  . SOAP:
62    . SoapClient::$httpurl is now a Soap\Url object rather than a resource.
63      Checks using is_resource() (i.e. is_resource($client->httpurl)) should be
64      replaced with checks for null (i.e. $client->httpurl !== null).
65    . SoapClient::$sdl is now a Soap\Sdl object rather than a resource.
66      Checks using is_resource() (i.e. is_resource($client->sdl)) should be
67      replaced with checks for null (i.e. $client->sdl !== null).
68
69- New warnings and exceptions:
70  . Curl:
71    . curl_multi_select throws a ValueError if the timeout argument if it's negative
72      or greater than PHP_INT_MAX.
73  . GD:
74    . imagejpeg/imagewebp/imagepng/imageavif throws an exception if an invalid
75      quality parameter value is passed. In addition, imageavif will throw an exception
76      if an invalid speed parameter value is passed.
77    . imagescale throws an exception if the width/height argument underflows/overflows or
78      if the mode argument is invalid.
79      imagefilter with IMG_FILTER_SCATTER throws an exception if the sub/plus arguments
80      underflows/overflows.
81  . Gettext:
82    . bind_textdomain_codeset, textdomain and d(*)gettext functions now throw an exception
83      if the domain argument is empty.
84  . Intl:
85    . resourcebundle_get(), ResourceBundle::get(), and accessing offsets on a
86      ResourceBundle object now throw:
87      - TypeError for invalid offset types
88      - ValueError for an empty string
89      - ValueError if the integer index does not fit in a signed 32 bit integer
90    . IntlDateFormatter::__construct() throws a ValueError if the locale is invalid.
91    . NumberFormatter::__construct() throws a ValueError if the locale is invalid.
92  . MBString:
93    . mb_encode_numericentity() and mb_decode_numericentity() now check that
94      the $map is only composed of integers, if not a ValueError is thrown.
95    . mb_http_input() now always throws a ValueError if the $type is invalid.
96    . mb_http_output() now checks that the $encoding parameter does not
97      contain any null bytes. If it does, a ValueError is now thrown.
98  . ODBC:
99    . odbc_fetch_row() now emits a warning when a value less than or equal to 0 is
100      passed for parameter $row.
101  . PCNTL:
102    . The functions pcntl_sigprocmask(), pcntl_sigwaitinfo() and
103      pcntl_sigtimedwait() now throw:
104      - A ValueError if the $signals array is empty (except for
105        pcntl_sigprocmask() if the $mode is SIG_SETMASK).
106      - A TypeError if a value of the $signals array is not an integer
107      - A ValueError if a value of the $signals array is not a valid signal number
108    . The function pcntl_sigprocmask() now throw:
109      - A ValueError if $mode is not one of SIG_BLOCK, SIG_UNBLOCK, or SIG_SETMASK
110    . The function pcntl_sigtimedwait() now throw:
111      - A ValueError if $seconds is less than 0
112      - A ValueError if $nanoseconds is less than 0 or greater than 1e9
113      - A ValueError if both $seconds and $nanoseconds are 0
114  . SimpleXML:
115    . Calling simplexml_import_dom() with a non-XML object now throws a
116      TypeError instead of a ValueError.
117  . Standard:
118    . round() now validates the value of the $mode parameter and throws a
119      ValueError for invalid modes. Previously invalid modes would have been
120      interpreted as PHP_ROUND_HALF_UP.
121    . The str_getcsv() function now throws ValueErrors when the $separator and
122      $enclosure arguments are not one byte long, or if the $escape is not one
123      byte long or the empty string. This aligns the behaviour to be identical
124      to that of fputcsv() and fgetcsv().
125    . php_uname() now throws ValueErrors if the $move parameter is invalid.
126    . The "allowed_classes" option for unserialize() now throws TypeErrors and
127      ValueErrors if it is not an array of class names.
128  . XMLReader:
129    . Passing an invalid character encoding to XMLReader::open() or
130      XMLReader::XML() now throws a ValueError.
131    . Passing a string containing null bytes previously emitted a
132      warning and now throws a ValueError as well.
133  . XMLWriter:
134    . Passing a string containing null bytes previously emitted a
135      warning and now throws a ValueError as well.
136  . XSL:
137    . XSLTProcessor::setParameter() will now throw a ValueError when its
138      arguments contain null bytes. This never actually worked correctly in
139      the first place, which is why it throws an exception nowadays.
140    . Calling XSLTProcessor::importStyleSheet() with a non-XML object now
141      throws a TypeError instead of a ValueError.
142    . Failure to call a PHP function callback during evaluation now throws
143      instead of emitting a warning.
144      RFC: https://wiki.php.net/rfc/improve_callbacks_dom_and_xsl
145
146- DOM:
147  . Some DOM methods previously returned false or a PHP_ERR DOMException if a new
148    node could not be allocated. They consistently throw an INVALID_STATE_ERR
149    DOMException now. This situation is extremely unlikely though and probably
150    will not affect you. As a result DOMImplementation::createDocument() now has
151    a tentative return type of DOMDocument instead of DOMDocument|false.
152  . Previously, DOMXPath objects could be cloned, but resulted in an unusable
153    object. This is no longer possible, and cloning a DOMXPath object now throws
154    an error.
155  . Removed DOMImplementation::getFeature().
156    RFC: https://wiki.php.net/rfc/deprecations_php_8_4#remove_domimplementationgetfeature_feature_version
157
158- GMP:
159  . The GMP class is now final and cannot be extended anymore.
160    RFC: https://wiki.php.net/rfc/gmp-final
161
162- MBString:
163  . On invalid strings (those with encoding errors), mb_substr() now interprets
164    character indices in the same manner as most other mbstring functions. This
165    means that character indices returned by mb_strpos() can be passed to mb_substr().
166  . For SJIS-Mac (MacJapanese) strings, character indices passed to mb_substr() now
167    refer to the indices of the Unicode codepoints which are produced when the string
168    is converted to Unicode. This is significant because around 40 SJIS-Mac characters
169    convert to a sequence of multiple Unicode codepoints.
170
171- Mysqli:
172  . The unused and undocumented constant MYSQLI_SET_CHARSET_DIR
173    has been removed.
174  . The MYSQLI_STMT_ATTR_PREFETCH_ROWS constant has been removed.
175    The feature is unavailable with mysqlnd.
176  . The MYSQLI_CURSOR_TYPE_FOR_UPDATE and MYSQLI_CURSOR_TYPE_SCROLLABLE
177    constants have been removed. This functionality was never implemented,
178    neither with mysqlnd nor with libmysql.
179  . The unused MYSQLI_TYPE_INTERVAL constant, which is currently a stub
180    and an alias for MYSQLI_TYPE_ENUM, has been removed. There are no
181    plans to add such data type to MySQL yet, so it's unclear what its value
182    would finally be.
183
184- MySQLnd:
185  . The error code reported for MySQL server wait timeouts has been changed from 2006
186    to 4031 for MySQL server versions 8.0.24 and above.
187
188- Opcache:
189  . The JIT config defaults changed from opcache.jit=tracing and
190    opcache.jit_buffer_size=0 to opcache.jit=disable and
191    opcache.jit_buffer_size=64M, respectively. This does not affect the default
192    behavior, the JIT is still disabled by default. However, it is now disabled
193    through the opcache.jit setting, rather than opcache.jit_buffer_size. This
194    may affect users who previously enabled JIT through opcache.jit_buffer_size
195    exclusively, without also specifying a JIT mode using opcache.jit. To enable
196    JIT, set the opcache.jit config value accordingly.
197  . The maximum value of the opcache.interned_strings_buffer setting on 64bit
198    architectures is now 32767 (it was previously 4095).
199  . If JIT is enabled, PHP will now exit with a fatal error on startup in case
200    of JIT startup initialization issues.
201
202- PCNTL:
203  . The functions pcntl_sigprocmask(), pcntl_sigwaitinfo() and
204    pcntl_sigtimedwait() now always return false on failure.
205    In some case previously it could return the value -1.
206
207- PCRE:
208  . The bundled pcre2lib has been updated to version 10.44.
209    As a consequence, this means {,3} is now recognized as a quantifier instead
210    of as text. Furthermore, the meaning of some character classes in UCP mode
211    has changed. Consult https://github.com/PCRE2Project/pcre2/blob/master/NEWS
212    for a full changelog.
213
214- PDO_DBLIB:
215  . setAttribute, DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER and DBLIB_ATTR_DATETIME_CONVERT
216    have been changed to set value as a bool.
217
218- PDO_FIREBIRD:
219  . Since some Firebird C++ APIs are used now, this extension requires a C++
220    compiler to be built. This also implies that the extension has to be built
221    against fbclient 3.0 or higher.
222  . getAttribute, ATTR_AUTOCOMMIT has been changed to get the value as a bool.
223
224- PDO_MYSQL:
225  . getAttribute, ATTR_AUTOCOMMIT, ATTR_EMULATE_PREPARES, MYSQL_ATTR_DIRECT_QUERY have
226    been changed to get values as bool.
227
228- PDO_PGSQL:
229  . The DSN's credentials, when set, are given priority over their PDO
230    constructor counterparts, being closer to the documentation states.
231
232- SimpleXML:
233  . Get methods called, or casting to a string on a SimpleXMLElement will no
234    longer implicitly reset the iterator data, unless explicitly rewound.
235    For example, casting an element to a string within a foreach loop would
236    cause an infinite loop because it destroyed the current iterator data.
237    This is no longer the case as a consequence of the bugfixes for GH-12192,
238    GH-12208, #55098.
239
240- SOAP:
241  . SoapClient::$typemap is now an array rather than a resource.
242    Checks using is_resource() (i.e. is_resource($client->typemap)) should be
243    replaced with checks for null (i.e. $client->typemap !== null).
244  . The SOAP extension gained an optional dependency on the session extension.
245    If you build PHP without the session extension and with --enable-rtld-now,
246    you will experience errors on startup if you also use the SOAP extension.
247    To solve this, either don't use rtld-now or load the session extension.
248
249- Standard:
250  . strcspn() with empty $characters now returns the length of the string instead
251    of incorrectly stopping at the first NUL character. See GH-12592.
252  . http_build_query() now correctly handles backed enums.
253  . stream_bucket_make_writeable() and stream_bucket_new() will now return a
254    StreamBucket instance instead of an instance of stdClass.
255    RFC: https://wiki.php.net/rfc/dedicated_stream_bucket
256
257- Tidy:
258  . Failures in the constructor now throw exceptions rather than emitting
259    warnings and having a broken object.
260
261- XML:
262  . The xml_set_*_handler() functions now declare and check for an effective
263    signature of callable|string|null for the $handler parameters.
264    Moreover, values of type string that correspond to method names,
265    of object set with xml_set_object() are now checked to see if the method
266    exists on the class of the previously passed object.
267    This means that xml_set_object() must now always be called prior to setting
268    method names as callables.
269    Passing an empty string to disable the handler is still allowed,
270    but deprecated.
271
272========================================
2732. New Features
274========================================
275
276- Core:
277  . Added request_parse_body() function that allows parsing RFC1867 (multipart)
278    requests in non-POST HTTP requests.
279    RFC: https://wiki.php.net/rfc/rfc1867-non-post
280  . Getting the debug info for WeakReference will now also output the object
281    it references, or null if the reference is no longer valid.
282  . The output of Closure::__debugInfo() now includes the name, file, and line
283    of the Closure.
284  . new expressions with constructor arguments are now dereferencable, meaning
285    they allow chaining method calls, property accesses, etc. without enclosing
286    the expression in parentheses.
287    RFC: https://wiki.php.net/rfc/new_without_parentheses
288  . Added the #[\Deprecated] attribute.
289    RFC: https://wiki.php.net/rfc/deprecated_attribute
290  . Implemented property hooks.
291    RFC: https://wiki.php.net/rfc/property-hooks
292  . Exiting a namespace now clears seen symbols. This allows using a symbol in a
293    namespace block, even if a previous namespace block declared a symbol with
294    the same name.
295    See Zend/tests/use_function/ns_end_resets_seen_symbols_1.phpt.
296  . Implemented asymmetric property visibility.
297    RFC: https://wiki.php.net/rfc/asymmetric-visibility-v2
298  . Implemented lazy objects.
299    RFC: https://wiki.php.net/rfc/lazy-objects
300
301- Curl:
302  . curl_version() returns an additional feature_list value, which is an
303    associative array of all known Curl features, and whether they are
304    supported (true) or not (false).
305  . Added CURL_HTTP_VERSION_3 and CURL_HTTP_VERSION_3ONLY constants (available
306    since libcurl 7.66 and 7.88) as available options for CURLOPT_HTTP_VERSION.
307  . Added CURLOPT_PREREQFUNCTION as a Curl option that accepts a callback to
308    be called after the connection is made, but before the request is sent.
309    The callback must return either CURL_PREREQFUNC_OK or CURL_PREREQFUNC_ABORT
310    to allow or abort the request.
311  . Added CURLOPT_SERVER_RESPONSE_TIMEOUT, which was formerly known as
312    CURLOPT_FTP_RESPONSE_TIMEOUT. Both constants hold the same value.
313  . Added CURLOPT_DEBUGFUNCTION support. This Curl option accepts a callable
314    that gets called during the request lifetime with the CurlHandle object,
315    an integer containing the debug message type, and a string containing the
316    debug message. The debug message type is one of CURLINFO_TEXT, CURLINFO_HEADER_IN,
317    CURLINFO_HEADER_OUT, CURLINFO_DATA_IN, CURLINFO_DATA_OUT, CURLINFO_SSL_DATA_OUT,
318    CURLINFO_SSL_DATA_IN constants. Once this option is set, CURLINFO_HEADER_OUT
319    must not be set because it uses the same libcurl functionality.
320  . curl_getinfo() function now returns "posttransfer_time_us", containing the
321    number of microseconds from the start until the last byte is sent. When a
322    redirect is followed, the time from each request is added together. This
323    value can also be retrieved by passing CURLINFO_POSTTRANSFER_TIME_T to the
324    curl_getinfo() $option parameter. This requires libcurl 8.10.0 or later.
325
326- DOM:
327  . Added DOMNode::compareDocumentPosition()
328  . Added constant DOMNode::DOCUMENT_POSITION_DISCONNECTED.
329  . Added constant DOMNode::DOCUMENT_POSITION_PRECEDING.
330  . Added constant DOMNode::DOCUMENT_POSITION_FOLLOWING.
331  . Added constant DOMNode::DOCUMENT_POSITION_CONTAINS.
332  . Added constant DOMNode::DOCUMENT_POSITION_CONTAINED_BY.
333  . Added constant DOMNode::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC.
334  . It is now possible to pass any callable to registerPhpFunctions().
335    RFC: https://wiki.php.net/rfc/improve_callbacks_dom_and_xsl
336
337- FPM:
338  . Flushing headers without a body will now succeed. See GH-12785.
339  . Status page has a new field to display a memory peak.
340
341- Intl:
342  . NumberFormatter::ROUND_HALFODD added to complement existing
343    NumberFormatter::ROUND_HALFEVEN functionality.
344
345- OpenSSL:
346  . Added support for Curve25519 + Curve448 based keys. Specifically x25519,
347    ed25519, x448 and ed448 fields are supported in openssl_pkey_new and
348    openssl_pkey_get_details as well as openssl_sign and openssl_verify were
349    extended to support those keys.
350  . Implement PASSWORD_ARGON2 password hashing.
351    Requires OpenSSL 3.2 and NTS build.
352
353- PCRE:
354  . The bundled pcre2lib has been updated to version 10.44.
355    As a consequence, LoongArch JIT support has been added, spaces
356    are now allowed between braces in Perl-compatible items, and
357    variable-length lookbehind assertions are now supported.
358  . With pcre2lib version 10.44, the maximum length of named capture groups
359    has changed from 32 to 128.
360  . Added support for the "r" (PCRE2_EXTRA_CASELESS_RESTRICT) modifier, as well
361    as the (?r) mode modifier. When enabled along with the case-insensitive
362    modifier ("i"), the expression locks out mixing of ASCII and non-ASCII
363    characters.
364
365- PDO:
366  . Added support for driver-specific subclasses.
367    RFC: https://wiki.php.net/rfc/pdo_driver_specific_subclasses
368    This RFC adds subclasses for PDO in order to better support
369    database-specific functionalities. The new classes are
370    instantiatable either via calling the PDO::connect() method
371    or by invoking their constructor directly.
372  . Added support for driver specific SQL parsers. The default parser supports:
373    - single and double quoted literals, with doubling as escaping mechanism.
374    - two-dashes and non-nested C-style comments.
375    RFC: https://wiki.php.net/rfc/pdo_driver_specific_parsers
376
377- PDO_MYSQL:
378  . Added custom parser supporting:
379    - single and double-quoted literals, with doubling and backslash as escaping
380      mechanism
381    - backtick literal identifiers and with doubling as escaping mechanism
382    - two dashes followed by at least 1 whitespace, non-nested C-style comments,
383      and hash-comments
384    RFC: https://wiki.php.net/rfc/pdo_driver_specific_parsers
385
386- PDO_PGSQL:
387  . Added custom parser supporting:
388    - single and double quoted literals, with doubling as escaping mechanism
389    - C-style "escape" string literals (E'string')
390    - dollar-quoted string literals
391    - two-dashes and C-style comments (non-nested)
392    - support for "??" as escape sequence for the "?" operator
393    RFC: https://wiki.php.net/rfc/pdo_driver_specific_parsers
394
395- PDO_SQLITE:
396  . Added custom parser supporting:
397    - single, double quoted, and backtick literals, with doubling as escaping mechanism
398    - square brackets quoting for identifiers
399    - two-dashes and C-style comments (non-nested)
400    RFC: https://wiki.php.net/rfc/pdo_driver_specific_parsers
401
402- Phar:
403  . Added support for the unix timestamp extension for zip archives.
404
405- Readfile:
406  . Added ability to change .php_history path through PHP_HISTFILE env variable.
407
408- Reflection:
409  . ReflectionAttribute now contains a $name property to improve the debugging
410    experience.
411  . ReflectionClassConstant::__toString() and ReflectionProperty::__toString()
412    now returns the attached doc comments.
413  . Multiple methods and constants related to lazy objects were introduced:
414    - ReflectionClass::newLazyGhost()
415    - ReflectionClass::newLazyProxy()
416    - ReflectionClass::resetAsLazyGhost()
417    - ReflectionClass::resetAsLazyProxy()
418    - ReflectionClass::isUninitializedLazyObject()
419    - ReflectionClass::initializeLazyObject()
420    - ReflectionClass::markLazyObjectAsInitialized()
421    - ReflectionClass::getLazyInitializer()
422    - ReflectionProperty::skipLazyInitialization()
423    - ReflectionProperty::setRawValueWithoutLazyInitialization()
424    - ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE
425    - ReflectionClass::SKIP_DESTRUCTOR
426    RFC: https://wiki.php.net/rfc/lazy-objects
427
428- SOAP:
429  . Added support for clark notation for namespaces in class map.
430    It is now possible to specify entries in a class map with clark notation
431    to resolve a type with a specific namespace to a specific class.
432    For example: '{http://example.com}foo' => 'FooClass'.
433  . Instances of DateTimeInterface that are passed to xsd:datetime or similar
434    elements are now serialized as such instead of being serialized as an
435    empty string.
436  . Session persistence now works with a shared session module.
437
438- Standard:
439  . Added a new RoundingMode enum with clearer naming and improved discoverability
440    compared to the PHP_ROUND_* constants.
441    RFC: https://wiki.php.net/rfc/correctly_name_the_rounding_mode_and_make_it_an_enum
442
443- XSL:
444  . It is now possible to use parameters that contain both single and double
445    quotes.
446  . It is now possible to pass any callable to registerPhpFunctions().
447    RFC: https://wiki.php.net/rfc/improve_callbacks_dom_and_xsl
448  . Added XSLTProcessor::$maxTemplateDepth and XSLTProcessor::$maxTemplateVars
449    to control the recursion depth of XSL template evaluation.
450
451- Zip:
452  . Added ZipArchive::ER_TRUNCATED_ZIP added in libzip 1.11
453
454========================================
4553. Changes in SAPI modules
456========================================
457
458- apache2handler
459  . Support for EOL Apache 2.0 and 2.2 has been removed. Minimum required Apache
460    version is now 2.4.
461
462- CLI:
463  . The builtin server looks for an index file recursively by traversing parent
464    directories in case the specified file cannot be located. This process was
465    previously skipped if the path looked like it was referring to a file, i.e.
466    if the last path component contained a period. In that case, a 404 error was
467    returned. The behavior has been changed to look for an index file in all
468    cases.
469
470- FPM:
471  . /dev/poll events.mechanism setting for Solaris/Illumos had been retired.
472
473========================================
4744. Deprecated Functionality
475========================================
476
477- Core:
478  . Implicitly nullable parameter types are now deprecated.
479    RFC: https://wiki.php.net/rfc/deprecate-implicitly-nullable-types
480  . Passing E_USER_ERROR to trigger_error() is now deprecated.
481    RFC: https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_passing_e_user_error_to_trigger_error
482  . Using "_" as a class name is now deprecated.
483    RFC: https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_using_a_single_underscore_as_a_class_name
484  . Raising zero to the power of negative number is deprecated.
485    RFC: https://wiki.php.net/rfc/raising_zero_to_power_of_negative_number
486  . The E_STRICT constant was deprecated and its corresponding error level was
487    removed.
488    RFC: https://wiki.php.net/rfc/deprecations_php_8_4#remove_e_strict_error_level_and_deprecate_e_strict_constant
489
490- Curl:
491  . The CURLOPT_BINARYTRANSFER constant is deprecated.
492
493- Date:
494  . Calling DatePeriod::__construct(string $isostr, int $options = 0) is
495    deprecated. Use DatePeriod::createFromISO8601String() instead.
496  . Constants SUNFUNCS_RET_TIMESTAMP, SUNFUNCS_RET_STRING, and
497    SUNFUNCS_RET_DOUBLE are now deprecated, following the deprecation of
498    the associated date_sunset() and date_sunrise() functions in PHP 8.1.
499    RFC: https://wiki.php.net/rfc/deprecations_php_8_4#constants_sunfuncs_ret_string_sunfuncs_ret_double_sunfuncs_ret_timestamp
500
501- DBA:
502  . Passing null or false to dba_key_split() is deprecated.
503    RFC: https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_passing_null_and_false_to_dba_key_split
504
505- DOM:
506  . Deprecated DOM_PHP_ERR constant.
507    RFC: https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_dom_php_err_constant
508  . DOMDocument::$actualEncoding, DOMDocument::config, DOMEntity::$actualEncoding,
509    DOMEntity::$encoding, DOMEntity::$version have been deprecated.
510    RFC: https://wiki.php.net/rfc/deprecations_php_8_4#formally_deprecate_soft-deprecated_domdocument_and_domentity_properties
511
512- Hash:
513  . Deprecated passing incorrect data types for options to ext/hash functions.
514    RFC: https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_passing_incorrect_data_types_for_options_to_exthash_functions
515
516- Intl:
517  . Calling intlcal_set() as well as calling IntlCalendar::set() with
518    more than 2 arguments is deprecated. Use either IntlCalendar::setDate()
519    or IntlCalendar::setDateTime() instead.
520  . Calling intlgregcal_create_instance() as well as calling
521    IntlGregorianCalendar::__construct() with more than 2 arguments is
522    deprecated. Use either IntlGregorianCalendar::createFromDate() or
523    IntlGregorianCalendar::createFromDateTime() instead.
524
525- LDAP:
526  . Calling ldap_connect() with more than 2 arguments is deprecated. Use
527    ldap_connect_wallet() instead.
528  . Calling ldap_exop() with more than 4 arguments is deprecated. Use
529    ldap_exop_sync() instead.
530
531- Mysqli:
532  . The mysqli_ping() function and mysqli::ping() method are now deprecated,
533    as the reconnect feature was removed in PHP 8.2.
534    RFC: https://wiki.php.net/rfc/deprecations_php_8_4#mysqli_ping_and_mysqliping
535  . The mysqli_kill() function and mysqli::kill() method are now deprecated.
536    If this functionality is needed a SQL "KILL" command can be used instead.
537    RFC: https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_mysqli_kill
538  . The mysqli_refresh() function and mysqli::refresh() method are now deprecated.
539    If this functionality is needed a SQL "FLUSH" command can be used instead.
540    All MYSQLI_REFRESH_* constants have been deprecated as well.
541    RFC: https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_mysqli_refresh
542  . Passing explicitly the $mode parameter to mysqli_store_result() has been
543    deprecated. As the MYSQLI_STORE_RESULT_COPY_DATA constant was only used in
544    conjunction with this function it has also been deprecated.
545    RFC: https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_the_second_parameter_to_mysqli_store_result
546
547- PDO_PGSQL:
548  . Using escaped question marks (??) inside dollar-quoted strings is deprecated.
549    Since PDO_PGSQL has its own SQL parser with dollar-quoted strings support, it
550    is no longer necessary to escape question marks inside them.
551
552- PgSQL:
553  . Calling pg_fetch_result() with 2 arguments is deprecated. Use the
554    3-parameter signature with a null $row parameter instead.
555  . Calling pg_field_prtlen() with 2 arguments is deprecated. Use the
556    3-parameter signature with a null $row parameter instead.
557  . Calling pg_field_is_null() with 2 arguments is deprecated. Use the
558    3-parameter signature with a null $row parameter instead.
559
560- Random:
561  . lcg_value() is deprecated, as the function is broken in multiple ways.
562    Use \Random\Randomizer::getFloat() instead.
563    RFC: https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_lcg_value
564
565- Reflection:
566  . Calling ReflectionMethod::__construct() with 1 argument is deprecated.
567    Use ReflectionMethod::createFromMethodName() instead.
568
569- Session:
570  . Calling session_set_save_handler() with more than 2 arguments is
571    deprecated. Use the 2-parameter signature instead.
572  . Changing the INI settings session.sid_length and session.sid_bits_per_character
573    is deprecated. Update the session storage backend to accept 32 character
574    hexadecimal session IDs and stop changing these two INI settings.
575    RFC: https://wiki.php.net/rfc/deprecations_php_8_4#sessionsid_length_and_sessionsid_bits_per_character
576  . Changing the INI settings session.use_only_cookies, session.use_trans_sid,
577    session.trans_sid_tags, session.trans_sid_hosts, and session.referer_check
578    is deprecated. The SID constant is also deprecated.
579    RFC: https://wiki.php.net/rfc/deprecate-get-post-sessions
580
581- SOAP:
582  . Passing an int to SoapServer::addFunction() is now deprecated.
583    If all PHP functions need to be provided flatten the array returned by
584    get_defined_functions().
585    RFC: https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_soap_functions_all_constant_and_passing_it_to_soapserveraddfunction
586  . The SOAP_FUNCTIONS_ALL constant is now deprecated.
587    RFC: https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_soap_functions_all_constant_and_passing_it_to_soapserveraddfunction
588
589- SPL:
590  . The SplFixedArray::__wakeup() method has been deprecated as it implements
591    __serialize() and __unserialize() which need to be overwritten instead.
592  . Using the default value for $escape parameter of:
593    - SplFileObject::setCsvControl()
594    - SplFileObject::fputcsv()
595    - SplFileObject::fgetcsv()
596    is now deprecated. It must be passed explicitly either positionally or via named arguments.
597    RFC: https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_proprietary_csv_escaping_mechanism
598
599- Standard:
600  . Calling stream_context_set_option() with 2 arguments is deprecated.
601    Use stream_context_set_options() instead.
602  . Unserializing strings using the uppercase 'S' tag is deprecated.
603    RFC: https://wiki.php.net/rfc/deprecations_php_8_4#unserialize_s_s_tag
604  . Using the default value for $escape parameter of:
605    - fputcsv()
606    - fgetcsv()
607    - str_getcsv()
608    is now deprecated. It must be passed explicitly either positionally or via named arguments.
609    RFC: https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_proprietary_csv_escaping_mechanism
610
611- XML:
612  . The xml_set_object() function has been deprecated.
613    RFC: https://wiki.php.net/rfc/deprecations_php_8_4#xml_set_object_and_xml_set_handler_with_string_method_names
614  . Passing non-callable strings to the xml_set_*_handler() functions is now
615    deprecated.
616    RFC: https://wiki.php.net/rfc/deprecations_php_8_4#xml_set_object_and_xml_set_handler_with_string_method_names
617
618========================================
6195. Changed Functions
620========================================
621
622- Core:
623  . trigger_error() and user_error() now have a return type of true instead of
624    bool.
625
626- DOM:
627  . DOMDocument::registerNodeClass() now has a tentative return type of true.
628    Previously, the return type was bool but only true could be returned in practice.
629
630- Hash:
631  . Changed the return type of hash_update() to true. It was already the case that only
632    true could be returned, but the stub was not updated yet.
633
634- Intl:
635  . NumberFormatter::ROUND_TOWARD_ZERO and NumberFormatter::ROUND_AWAY_FROM_ZERO
636    have been added as aliases for NumberFormatter::ROUND_DOWN and
637    NumberFormatter::ROUND_UP to be consistent with the new PHP_ROUND_* modes.
638    RFC: https://wiki.php.net/rfc/new_rounding_modes_to_round_function
639  . ResourceBundle::get() now has a tentative return type of:
640    ResourceBundle|array|string|int|null
641  . The idn_to_ascii() and idn_to_utf8() now always throw ValueErrors if the
642    $domain name is empty or too long, and if $variant is not
643    INTL_IDNA_VARIANT_UTS46.
644
645- LibXML:
646  . libxml_set_streams_context() now immediately throws a TypeError when a
647    non-stream-context resource is passed to the function, instead of throwing
648    later when the stream context is used.
649
650- MBString:
651  . The behavior of mb_strcut is more consistent now on invalid UTF-8 and UTF-16
652    strings. (For valid UTF-8 and UTF-16 strings, there is no change.)
653
654- ODBC:
655  . Parameter $row of odbc_fetch_object(), odbc_fetch_array(), and
656    odbc_fetch_into() now has a default value of null, consistent with
657    odbc_fetch_row(). Previously, the default values were -1, -1, and 0,
658    respectively.
659
660- OpenSSL:
661  . The extra_attributes parameter in openssl_csr_new sets CSR attributes
662    instead of subject DN which was incorrectly done previously.
663  . The dn parameter in openssl_csr_new allows setting array of values for
664    a single entry.
665  . New serial_hex parameter added to openssl_csr_sign to allow setting serial
666    number in the hexadecimal format.
667  . Parsing ASN.1 UTCTime by openssl_x509_parse fails if seconds are omitted
668    for OpenSSL version below 3.2 (-1 is returned for such fields). The
669    OpenSSL version 3.3+ does not load such certificates already.
670
671- Output:
672  . Output handler status flags passed to the flags parameter of ob_start
673    are now cleared.
674
675- PDO:
676  . getAttribute, enabled to get the value of ATTR_STRINGIFY_FETCHES.
677
678- PDO_FIREBIRD:
679  . getAttribute, enabled to get values of FB_ATTR_DATE_FORMAT, FB_ATTR_TIME_FORMAT,
680    FB_ATTR_TIMESTAMP_FORMAT.
681  . Added new attributes to specify transaction isolation level and access mode.
682    Along with these, five constants (Pdo\Firebird::TRANSACTION_ISOLATION_LEVEL,
683    Pdo\Firebird::READ_COMMITTED, Pdo\Firebird::REPEATABLE_READ,
684    Pdo\Firebird::SERIALIZABLE, Pdo\Firebird::WRITABLE_TRANSACTION) have been added.
685  . When using persistent connections, there is now a liveness check in the
686    constructor.
687  . The content that is built changes depending on the value of FB_API_VER in
688    ibase.h, so added static method Pdo\Firebird::getApiVersion() to obtain that
689    value. This value can also be referenced from phpinfo.
690  . Five new data types are now available: INT128, DEC16, DEC34, TIMESTAMP_TZ, TIME_TZ.
691    These are available starting with Firebird 4.0.
692
693- PDO_MYSQL:
694  . getAttribute, enabled to get the value of ATTR_FETCH_TABLE_NAMES.
695
696- PDO_PGSQL:
697  . getAttribute() can now retrieve the memory usage of query results.
698    PDO::PGSQL_ATTR_RESULT_MEMORY_SIZE was added for this feature.
699  . If the column is of FLOAT4OID/FLOAT8OID type, query returns it as a
700    float instead of a string.
701
702- PGSQL:
703  . pg_select, the conditions arguments accepts an empty array and is optional.
704
705- Phar:
706  . Phar::setAlias() and Phar::setDefaultStub() methods now have a tentative
707    return type of true instead of bool.
708
709- POSIX:
710  . posix_isatty now sets the error number when the file descriptor/stream argument
711    is invalid.
712
713- Reflection:
714  . ReflectionGenerator::getFunction() may now be called after the generator
715    finished executing.
716
717- Sockets:
718  . Parameter $backlog of socket_create_listen() now has a default value of SOMAXCONN.
719    Previously, it was 128.
720
721- SPL:
722  . SplPriorityQueue::insert() and SplPriorityQueue::recoverFromCorruption()
723    now has a tentative return type of true
724  . SplHeap::insert() and SplHeap::recoverFromCorruption()
725    now has a tentative return type of true instead of bool
726
727- Standard:
728  . The internal implementation for rounding to integers has been rewritten
729    to be easier to verify for correctness and to be easier to maintain.
730    Some rounding bugs have been fixed as a result of the rewrite. For
731    example previously rounding 0.49999999999999994 to the nearest integer
732    would have resulted in 1.0 instead of the correct result 0.0. Additional
733    inputs might also be affected and result in different outputs compared to
734    earlier PHP versions.
735  . The $mode parameter of the round() function has been widened to RoundingMode|int,
736    accepting instances of a new RoundingMode enum.
737    RFC: https://wiki.php.net/rfc/correctly_name_the_rounding_mode_and_make_it_an_enum
738  . Four new modes have been added to the round() function: RoundingMode::PositiveInfinity,
739    RoundingMode::NegativeInfinity, RoundingMode::TowardsZero, RoundingMode::AwayFromZero.
740    RFC: https://wiki.php.net/rfc/new_rounding_modes_to_round_function
741  . Fixed a bug caused by "pre-rounding" of the round() function. Previously, using
742    "pre-rounding" to treat a value like 0.285 (actually 0.28499999999999998) as a
743    decimal number and round it to 0.29. However, "pre-rounding" incorrectly rounds
744    certain numbers, so this fix removes "pre-rounding" and changes the way numbers
745    are compared, so that the values are correctly rounded as decimal numbers.
746  . The maximum precision that can be handled by round() has been extended by one
747    digit. For example, `round(4503599627370495.5)` returned in `4503599627370495.5`,
748    but now returns `4503599627370496`.
749  . The default value of the 'cost' option for PASSWORD_BCRYPT for password_hash()
750    has been increased from '10' to '12'.
751    RFC: https://wiki.php.net/rfc/bcrypt_cost_2023
752  . debug_zval_dump() now indicates whether an array is packed.
753  . long2ip() now returns string instead of string|false.
754  . output_add_rewrite_var() now uses url_rewriter.hosts instead of
755    session.trans_sid_hosts for selecting hosts that will be rewritten.
756  . highlight_string() now has a return type of string|true instead of string|bool.
757  . print_r() now has a return type of string|true instead of string|bool.
758
759========================================
7606. New Functions
761========================================
762
763- Core:
764  . request_parse_body()
765
766- BCMath:
767  . Added bcfloor(), bcceil(), bcround().
768    RFC: https://wiki.php.net/rfc/adding_bcround_bcfloor_bcceil_to_bcmath
769  . Added bcdivmod().
770    RFC: https://wiki.php.net/rfc/add_bcdivmod_to_bcmath
771
772- Date:
773  . Added static methods
774    DateTime[Immutable]::createFromTimestamp(int|float $timestamp): static.
775  . Added method DateTime[Immutable]::getMicrosecond(): int.
776  . Added method
777    DateTime[Immutable]::setMicrosecond(int $microsecond): static.
778
779- DOM:
780  . Added DOMNode::compareDocumentPosition().
781  . Added DOMXPath::registerPhpFunctionNS().
782    RFC: https://wiki.php.net/rfc/improve_callbacks_dom_and_xsl
783  . Added DOMXPath::quote() to quote a string for use in an XPath expression.
784    Example usage: "//span[contains(text()," . $xpath->quote($string) . ")]"
785
786- Hash:
787  . Added HashContext::__debugInfo().
788
789- Intl:
790  . Added IntlTimeZone::getIanaID()/intltz_get_iana_id() to
791    the IANA identifier from a given timezone.
792  . Added grapheme_str_split which allow to support emoji and Variation
793    Selectors.
794    RFC: https://wiki.php.net/rfc/grapheme_str_split
795  . Added IntlDateFormatter::parseToCalendar which behaves like
796    IntlDateFormatter::parse except the time zone is updated.
797  . Added SpoofChecker::setAllowedChars to limit the range of unicode
798    chars.
799
800- MBString:
801  . Added mb_trim, mb_ltrim and mb_rtrim functions.
802    RFC: https://wiki.php.net/rfc/mb_trim
803    Note: this was amended by GH-13820 to fix GH-13815.
804  . Added mb_ucfirst and mb_lcfirst functions.
805    RFC: https://wiki.php.net/rfc/mb_ucfirst
806
807- OPCache:
808  . Added opcache_jit_blacklist function. It allows skipping the tracing JIT
809    execution of select functions.
810
811- PCNTL:
812  . Added pcntl_setns allowing a process to be reassociated with a namespace in order
813    to share resources with other processes within this context.
814  . Added pcntl_getcpuaffinity to get the cpu(s) bound to a process and
815    pcntl_setcpuaffinity to bind 1 or more cpus to a process.
816  . Added pcntl_getcpu to get the cpu id from where the current process runs.
817  . Added pcntl_getqos_class to get the QoS level (aka performance and related
818    energy consumption) of the current process and pcntl_setqos_class to set it.
819  . Added pcntl_waitid to obtain status information pertaining to termination, stop,
820    and/or continue events in one of the caller's child processes.
821
822- PDO_PGSQL:
823  . Added Pdo\Pgsql::setNoticeCallback() to allow a callback to be triggered on
824    every notice sent (e.g. RAISE NOTICE).
825
826- PGSQL:
827  . Added pg_change_password to alter a given user's password. It handles
828    transparently the password encryption from the database settings.
829  . Added pg_put_copy_data to send COPY commands and pg_put_copy_end to send
830    end-of-data to the server.
831  . Added pg_socket_poll to check if there is any read and/or write events
832    with an optional timeout.
833  . Added pg_jit to get informations on the server JIT support.
834  . Added pg_set_chunked_rows_size to allow to fetch results in chunk of
835    max N rows.
836  . Added pg_result_memory_size to get the visibility the memory used by a query result.
837
838- Reflection:
839  . Multiple methods related to lazy objects were introduced:
840    - ReflectionClass::newLazyGhost()
841    - ReflectionClass::newLazyProxy()
842    - ReflectionClass::resetAsLazyGhost()
843    - ReflectionClass::resetAsLazyProxy()
844    - ReflectionClass::isUninitializedLazyObject()
845    - ReflectionClass::initializeLazyObject()
846    - ReflectionClass::markLazyObjectAsInitialized()
847    - ReflectionClass::getLazyInitializer()
848    - ReflectionProperty::skipLazyInitialization()
849    - ReflectionProperty::setRawValueWithoutLazyInitialization()
850    RFC: https://wiki.php.net/rfc/lazy-objects
851  . ReflectionClassConstant::isDeprecated() was introduced.
852  . ReflectionGenerator::isClosed() was introduced.
853  . ReflectionProperty::isDynamic() was introduced.
854
855- Sodium:
856  . Added the sodium_crypto_aead_aegis128l_*() and sodium_crypto_aead_aegis256l_*()
857    functions to support the AEGIS family of authenticated encryption algorithms,
858    that was introduced in libsodium 1.0.19.
859  . sodium_crypto_aead_aes256gcm_*() functions are now enabled on aarch64 CPUs
860    with the ARM cryptographic extensions.
861
862- SPL:
863  . Added seek() method to SplObjectStorage, now it implements
864    SeekableIterator.
865
866- SOAP:
867  . Added SoapServer::__getLastResponse(). This only tracks the last response
868    if the trace option is set to true in the SoapServer constructor's $options
869    argument.
870
871- Standard:
872  . Added the http_get_last_response_headers() and
873    http_clear_last_response_headers() that allows retrieving the same content
874    as the magic $http_response_header variable.
875    RFC: https://wiki.php.net/rfc/http-last-response-headers
876  . Added function fpow() following rules of IEEE 754.
877    RFC: https://wiki.php.net/rfc/raising_zero_to_power_of_negative_number
878  . Added functions array_find(), array_find_key(), array_all(), and
879    array_any().
880    RFC: https://wiki.php.net/rfc/array_find
881
882- Tidy:
883  . Added tidyNode::getNextSibling() and tidyNode::getPreviousSibling().
884
885- XMLReader:
886  . Added XMLReader::fromStream(), XMLReader::fromUri(), XMLReader::fromString().
887    RFC: https://wiki.php.net/rfc/xmlreader_writer_streams
888
889- XMLWriter:
890  . Added XMLWriter::toStream(), XMLWriter::toUri(), XMLWriter::toMemory().
891    RFC: https://wiki.php.net/rfc/xmlreader_writer_streams
892
893- XSL:
894  . Added XSLTProcessor::registerPhpFunctionNS().
895    RFC: https://wiki.php.net/rfc/improve_callbacks_dom_and_xsl
896
897========================================
8987. New Classes and Interfaces
899========================================
900
901- BCMath:
902  . Added BcMath\Number class. It is an immutable object, has methods that are
903    equivalent to existing BCMath calculation functions, and can also be calculated
904    using operators.
905    The existing BCMath function returned a string for each calculation, but this
906    class returns an object.
907    RFC: https://wiki.php.net/rfc/support_object_type_in_bcmath,
908    https://wiki.php.net/rfc/fix_up_bcmath_number_class
909
910- Core:
911  . RequestParseBodyException.
912    RFC: https://wiki.php.net/rfc/rfc1867-non-post
913  . #[\Deprecated] attribute.
914    RFC: https://wiki.php.net/rfc/deprecated_attribute
915
916- DBA:
917  . Dba\Connection opaque object replacing DBA resources
918
919- DOM:
920  . Implemented DOM HTML5 parsing and serialization.
921    RFC: https://wiki.php.net/rfc/domdocument_html5_parser.
922    This RFC adds the new Dom namespace along with new classes and
923    constant aliases.
924    There are two new classes to handle HTML and XML documents:
925    Dom\HTMLDocument and Dom\XMLDocument.
926    These classes provide a cleaner API to handle HTML and XML documents.
927    Furthermore, the Dom\HTMLDocument class implements spec-compliant HTML5
928    parsing and serialization.
929  . Implemented opt-in ext/dom spec compliance RFC.
930    This adds new classes in the DOM namespace that correspond to modern
931    equivalents to the old DOM classes in the global namespaces.
932    The new classes follow the DOM living spec.
933    RFC: https://wiki.php.net/rfc/opt_in_dom_spec_compliance
934  . Implemented "New ext-dom features in PHP 8.4" RFC.
935    RFC: https://wiki.php.net/rfc/dom_additions_84
936
937- ODBC:
938  . Odbc\Connection
939  . Odbc\Result
940
941- PDO_DBLIB:
942  . Pdo\DbLib.
943
944- PDO_FIREBIRD:
945  . Pdo\Firebird.
946
947- PDO_MYSQL:
948  . Pdo\Mysql.
949
950- PDO_ODBC:
951  . Pdo\Odbc.
952
953- PDO_PGSQL:
954  . Pdo\Pgsql.
955
956- PDO_SQLITE:
957  . Pdo\Sqlite.
958
959- Reflection:
960  . ReflectionConstant
961
962- SOAP:
963  . Soap\Url
964  . Soap\Sdl
965
966- Standard:
967  . StreamBucket
968
969========================================
9708. Removed Extensions and SAPIs
971========================================
972
973- IMAP:
974  . The IMAP extension has been unbundled and moved to PECL.
975    RFC: https://wiki.php.net/rfc/unbundle_imap_pspell_oci8
976
977- OCI8:
978  . The OCI8 extension has been unbundled and moved to PECL.
979    RFC: https://wiki.php.net/rfc/unbundle_imap_pspell_oci8
980
981- PDO_OCI:
982  . The PDO_OCI extension has been unbundled and moved to PECL.
983    RFC: https://wiki.php.net/rfc/unbundle_imap_pspell_oci8
984
985- PSpell:
986  . The pspell extension has been unbundled and moved to PECL.
987    RFC: https://wiki.php.net/rfc/unbundle_imap_pspell_oci8
988
989========================================
9909. Other Changes to Extensions
991========================================
992
993- Curl:
994  . The Curl extension now requires at least libcurl 7.61.0.
995  . The CURLOPT_DNS_USE_GLOBAL_CACHE Curl option no longer has any
996    effect, and is silently ignored. This underlying feature was
997    deprecated in libcurl 7.11.1 and removed in 7.62.0.
998
999- GMP:
1000  . Casting a GMP object to bool is now possible instead of emitting a
1001    E_RECOVERABLE_ERROR. The casting behaviour is overloaded such that a GMP
1002    object representing the value 0 is cast to false.
1003    RFC: https://wiki.php.net/rfc/fix_up_bcmath_number_class
1004
1005- Intl:
1006  . The behaviour of Intl class has been normalized to always throw Error
1007    exceptions when attempting to use a non-initialized object,
1008    or when cloning fails.
1009
1010- LibXML:
1011  . The libxml extension now requires at least libxml2 2.9.4.
1012
1013- MBString:
1014  . Unicode data tables have been updated to Unicode 16.0.
1015
1016- Mysqlnd:
1017  . Support for the new VECTOR data type from MySQL 9.
1018
1019- OpenSSL:
1020  . The OpenSSL extension now requires at least OpenSSL 1.1.1.
1021
1022- PDO_PGSQL:
1023  . The pdo_pgsql extension now requires at least libpq 10.0.
1024
1025- PgSQL:
1026  . The pgsql extension now requires at least libpq 10.0.
1027
1028- SPL:
1029  . Out of bounds accesses in SplFixedArray now throw an exception of type
1030    OutOfBoundsException instead of RuntimeException. As OutOfBoundsException
1031    is a child class of RuntimeException, code that uses RuntimeException
1032    continues to function.
1033
1034- XSL:
1035  . The typed properties XSLTProcessor::$cloneDocument and
1036    XSLTProcessor::$doXInclude are now declared.
1037
1038- zlib:
1039  . The zlib extension now requires at least zlib 1.2.11.
1040
1041========================================
104210. New Global Constants
1043========================================
1044
1045- Core:
1046  . PHP_OUTPUT_HANDLER_PROCESSED.
1047  . PHP_SBINDIR.
1048
1049- Curl:
1050  . CURL_HTTP_VERSION_3.
1051  . CURL_HTTP_VERSION_3ONLY.
1052  . CURLOPT_TCP_KEEPCNT.
1053  . CURLOPT_PREREQFUNCTION.
1054  . CURL_PREREQFUNC_OK.
1055  . CURL_PREREQFUNC_ABORT.
1056  . CURLOPT_SERVER_RESPONSE_TIMEOUT.
1057  . CURLOPT_DEBUGFUNCTION.
1058  . CURLINFO_TEXT.
1059  . CURLINFO_HEADER_IN.
1060  . CURLINFO_DATA_IN.
1061  . CURLINFO_DATA_OUT.
1062  . CURLINFO_SSL_DATA_OUT.
1063  . CURLINFO_SSL_DATA_IN.
1064  . CURLINFO_POSTTRANSFER_TIME_T.
1065
1066- Intl:
1067  . The IntlDateFormatter class exposes now the new PATTERN constant
1068    reflecting udat api's UDAT_PATTERN.
1069  . The IntlChar class exposes now the new PROPERTY_IDS_UNARY_OPERATOR (new
1070    IDS binary operator), PROPERTY_ID_COMPAT_MATH_START,
1071    PROPERTY_ID_COMPAT_MATH_CONTINUE (both for mathematical
1072    identifier profiling purpose) constants.
1073
1074- LDAP:
1075  . LDAP_OPT_X_TLS_PROTOCOL_MAX.
1076  . LDAP_OPT_X_TLS_PROTOCOL_TLS1_3.
1077
1078- LibXML:
1079  . LIBXML_RECOVER.
1080  . LIBXML_NO_XXE.
1081    This is used together with LIBXML_NOENT for when you want to perform entity
1082    substitution, but want to disallow external entity loading.
1083    This constant is available as of libxml2 2.13.
1084
1085- Mysqli:
1086  . MYSQLI_TYPE_VECTOR.
1087
1088- OpenSSL:
1089  . X509_PURPOSE_OCSP_HELPER.
1090  . X509_PURPOSE_TIMESTAMP_SIGN.
1091
1092- PCNTL:
1093  . Pcntl\QosClass::Background (macOs only).
1094  . Pcntl\QosClass::Default (macOs only).
1095  . Pctnl\QosClass::UserInteractive (macOs only).
1096  . Pcntl\QosClass::UserInitiated (macOs only).
1097  . Pcntl\QosClass::Utility (macOs only).
1098  . SIGCKPT (DragonFlyBSD only).
1099  . SIGCKPTEXIT (DragonFlyBSD only).
1100  . WEXITED.
1101  . WSTOPPED.
1102  . WNOWAIT.
1103  . P_ALL.
1104  . P_PID.
1105  . P_PGID.
1106  . P_PIDFD (Linux only).
1107  . P_UID (NetBSD/FreeBSD only).
1108  . P_GID (NetBSD/FreeBSD only).
1109  . P_SID (NetBSD/FreeBSD only).
1110  . P_JAILID (FreeBSD only).
1111
1112- PgSQL:
1113  . PGSQL_TUPLES_CHUNK
1114
1115- POSIX:
1116  . POSIX_SC_CHILD_MAX
1117  . POSIX_SC_CLK_TCK
1118
1119- Sockets:
1120  . SO_EXCLUSIVEADDRUSE (Windows only).
1121  . SOCK_CONN_DGRAM (NetBSD only).
1122  . SOCK_DCCP (NetBSD only).
1123  . TCP_SYNCNT (Linux only).
1124  . SO_EXCLBIND (Solaris/Illumos only).
1125  . SO_NOSIGPIPE (macOs and FreeBSD).
1126  . SO_LINGER_SEC (macOs only).
1127  . IP_PORTRANGE (FreeBSD/NetBSD/OpenBSD only).
1128  . IP_PORTRANGE_DEFAULT (FreeBSD/NetBSD/OpenBSD only).
1129  . IP_PORTRANGE_HIGH (FreeBSD/NetBSD/OpenBSD only).
1130  . IP_PORTRANGE_LOW (FreeBSD/NetBSD/OpenBSD only).
1131  . SOCK_NONBLOCK.
1132  . SOCK_CLOEXEC.
1133  . SO_BINDTOIFINDEX.
1134
1135- Sodium:
1136  . SODIUM_CRYPTO_AEAD_AEGIS128L_KEYBYTES
1137  . SODIUM_CRYPTO_AEAD_AEGIS128L_NSECBYTES
1138  . SODIUM_CRYPTO_AEAD_AEGIS128L_NPUBBYTES
1139  . SODIUM_CRYPTO_AEAD_AEGIS128L_ABYTES
1140  . SODIUM_CRYPTO_AEAD_AEGIS256_KEYBYTES
1141  . SODIUM_CRYPTO_AEAD_AEGIS256_NSECBYTES
1142  . SODIUM_CRYPTO_AEAD_AEGIS256_NPUBBYTES
1143  . SODIUM_CRYPTO_AEAD_AEGIS256_ABYTES
1144
1145- XML:
1146  . Added XML_OPTION_PARSE_HUGE to allow large inputs in xml_parse and
1147    xml_parse_into_struct.
1148    RFC: https://wiki.php.net/rfc/xml_option_parse_huge.
1149
1150========================================
115111. Changes to INI File Handling
1152========================================
1153
1154========================================
115512. Windows Support
1156========================================
1157
1158* Building with Visual Studio now requires at least Visual Studio 2019 (Visual
1159  Studio 2022 is recommended, though).
1160
1161* AVX(2) CPU support is now properly detected for MSVC builds.
1162
1163* Native AVX-512 builds are now supported (--enable-native-intrinsics=avx512).
1164
1165========================================
116613. Other Changes
1167========================================
1168
1169* Closure names have been adjusted to include the parent function's name
1170  and the line of definition to make them easier to distinguish, for example
1171  within stack traces.
1172
1173* run-tests.php now skips online tests by default. Set the SKIP_ONLINE_TESTS
1174  environment variable to 0, or pass the --online flag to run-tests.php to
1175  execute them.
1176
1177* Fiber switching during destructor execution is now allowed. It was previously
1178  blocked due to conflicts with garbage collection.
1179
1180  Destructors may now be executed in a separate Fiber:
1181
1182  When garbage collection is triggered in a Fiber, destructors called by the GC
1183  are executed in a separate Fiber: the gc_destructor_fiber. If this Fiber
1184  suspends, a new one is created to execute the remaining destructors. The
1185  previous gc_destructor_fiber is not referenced anymore by the GC and may be
1186  collected if it's not referenced anywhere else. Objects whose destructor is
1187  suspended will not be collected until the destructor returns or the Fiber is
1188  collected.
1189
1190========================================
119114. Performance Improvements
1192========================================
1193
1194- BCMath:
1195  . Improved performance of number conversions and operations.
1196
1197- Core:
1198  . Improved the performance of floating point number parsing and formatting in
1199    ZTS builds under highly concurrent loads. This affects the `printf()` family
1200    of functions as well as serialization functions such as `json_encode()`,
1201    `serialize()`.
1202  . `sprintf()` using only `%s` and `%d` will be compiled into the equivalent
1203    string interpolation, avoiding the overhead of a function call and repeatedly
1204    parsing the format string.
1205
1206- DOM:
1207  . The performance of DOMNode::C14N() is greatly improved for the case without
1208    an xpath query. This can give a time improvement of easily two order of
1209    magnitude for documents with tens of thousands of nodes.
1210  . Improved performance and reduce memory consumption of XML serialization.
1211  . Reduced memory usage of node classes.
1212
1213- FTP:
1214  . Improved the performance of FTP uploads up to a factor of 10x for large
1215    uploads.
1216
1217- Hash:
1218  . Added SSE2 and SHA-NI implementations of SHA-256. This improves the performance
1219    on supported CPUs by ~1.3x (SSE2) and 3x - 5x (SHA-NI).
1220
1221- MBString:
1222  . mb_strcut() is much faster now for UTF-8 and UTF-16 strings.
1223  . Looking up mbstring encoding names is much faster now.
1224  . The performance of converting SJIS-win to unicode is greatly improved.
1225
1226- MySQLnd:
1227  . Improved the performance of MySQLnd quoting.
1228
1229- PCRE:
1230  . Improved the performance of named capture groups.
1231
1232- Random:
1233  . Improved the performance of \Random\Randomizer, with a specific focus
1234    on the getBytes() and getBytesFromString() methods.
1235
1236- SimpleXML:
1237  . Improved performance and reduce memory consumption of XML serialization.
1238
1239- Standard:
1240  . Improved the performance of strpbrk().
1241  . The performance of strspn() and strcspn() is greatly improved.
1242    They now run in linear time instead of being bounded by quadratic time.
1243  . get_browser() is much faster now, up to 1.5x - 2.5x for some test cases.
1244
1245