1PHP 8.0 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 19======================================== 201. Backward Incompatible Changes 21======================================== 22 23- Core: 24 . `match` is now a reserved keyword. 25 . Assertion failures now throw by default. If the old behavior is desired, 26 then set `assert.exception=0` in INI settings. 27 . Methods with the same name as the class are no longer interpreted as 28 constructors. The __construct() method should be used instead. 29 . Removed ability to call non-static methods statically. 30 Thus `is_callable` will fail when checking for a non-static method with a 31 classname (must check with an object instance). 32 . Removed (real) cast. 33 . Removed (unset) cast. 34 . Removed track_errors ini directive. This means that $php_errormsg is no 35 longer available. The error_get_last() function may be used instead. 36 . Removed the ability to define case-insensitive constants. The third 37 argument to define() may no longer be true. 38 . Access to undefined constants now always results in an Error exception. 39 Previously, unqualified constant accesses resulted in a warning and were 40 interpreted as strings. 41 . Removed ability to specify an autoloader using an __autoload() function. 42 spl_autoload_register() should be used instead. 43 . Removed the $errcontext argument for custom error handlers. 44 . Removed create_function(). Anonymous functions may be used instead. 45 . Removed each(). foreach or ArrayIterator should be used instead. 46 . Removed ability to unbind $this from closures that were created from a 47 method, using Closure::fromCallable() or ReflectionMethod::getClosure(). 48 . Also removed ability to unbind $this from proper closures that contain uses 49 of $this. 50 . Removed ability to use array_key_exists() with objects. Use one of isset() 51 or property_exists() instead. 52 . Made the behavior of array_key_exists() regarding the type of the key 53 parameter consistent with isset() and normal array access. All key types now 54 use the usual coercions and array/object keys throw a TypeError. 55 . Any array that has a number n as its first numeric key will use n+1 for 56 its next implicit key, even if n is negative. 57 RFC: https://wiki.php.net/rfc/negative_array_index 58 . The default error_reporting level is now E_ALL. Previously it excluded 59 E_NOTICE and E_DEPRECATED. 60 . display_startup_errors is now enabled by default. 61 . Using "parent" inside a class that has no parent will now result in a 62 fatal compile-time error. 63 . The @ operator will no longer silence fatal errors (E_ERROR, E_CORE_ERROR, 64 E_COMPILE_ERROR, E_USER_ERROR, E_RECOVERABLE_ERROR, E_PARSE). Error handlers 65 that expect error_reporting to be 0 when @ is used, should be adjusted to 66 use a mask check instead: 67 68 // Replace 69 function my_error_handler($err_no, $err_msg, $filename, $linenum) { 70 if (error_reporting() == 0) { 71 return; // Silenced 72 } 73 // ... 74 } 75 76 // With 77 function my_error_handler($err_no, $err_msg, $filename, $linenum) { 78 if (!(error_reporting() & $err_no)) { 79 return; // Silenced 80 } 81 // ... 82 } 83 84 Additionally, care should be taken that error messages are not displayed in 85 production environments, which can result in information leaks. Please 86 ensure that display_errors=Off is used in conjunction with error logging. 87 . Following the hash comment operator # immediately with an opening bracket 88 is not supported as a comment anymore since this syntax is now used for 89 attributes. 90 RFC: https://wiki.php.net/rfc/shorter_attribute_syntax_change 91 . Inheritance errors due to incompatible method signatures (LSP violations) 92 will now always generate a fatal error. Previously a warning was generated 93 in some cases. 94 RFC: https://wiki.php.net/rfc/lsp_errors 95 . The precedence of the concatenation operator has changed relative to 96 bitshifts and addition as well as subtraction. 97 RFC: https://wiki.php.net/rfc/concatenation_precedence 98 . Arguments with a default value that resolves to null at runtime will no 99 longer implicitly mark the argument type as nullable. Either use an explicit 100 nullable type, or an explicit null default value instead. 101 102 // Replace 103 function test(int $arg = CONST_RESOLVING_TO_NULL) {} 104 // With 105 function test(?int $arg = CONST_RESOLVING_TO_NULL) {} 106 // Or 107 function test(int $arg = null) {} 108 . A number of warnings have been converted into Error exceptions: 109 110 * Attempting to write to a property of a non-object. Previously this 111 implicitly created an stdClass object for null, false and empty strings. 112 * Attempting to append an element to an array for which the PHP_INT_MAX key 113 is already used. 114 * Attempting to use an invalid type (array or object) as an array key or 115 string offset. 116 * Attempting to write to an array index of a scalar value. 117 * Attempting to unpack a non-array/Traversable. 118 119 A number of notices have been converted into warnings: 120 121 * Attempting to read an undefined variable. 122 * Attempting to read an undefined property. 123 * Attempting to read an undefined array key. 124 * Attempting to read a property of a non-object. 125 * Attempting to access an array index of a non-array. 126 * Attempting to convert an array to string. 127 * Attempting to use a resource as an array key. 128 * Attempting to use null, a boolean, or a float as a string offset. 129 * Attempting to read an out-of-bounds string offset. 130 * Attempting to assign an empty string to a string offset. 131 132 RFC: https://wiki.php.net/rfc/engine_warnings 133 . Attempting to assign multiple bytes to a string offset will now emit a 134 warning. 135 . Unexpected characters in source files (such as null bytes outside of 136 strings) will now result in a ParseError exception instead of a compile 137 warning. 138 . Uncaught exceptions now go through "clean shutdown", which means that 139 destructors will be called after an uncaught exception. 140 . Compile time fatal error "Only variables can be passed by reference" has 141 been delayed until runtime and converted to "Argument cannot be passed by 142 reference" exception. 143 . Some "Only variables should be passed by reference" notices have been 144 converted to "Argument cannot be passed by reference" exception. 145 . The generated name for anonymous classes has changed. It will now include 146 the name of the first parent or interface: 147 148 new class extends ParentClass {}; 149 // -> ParentClass@anonymous 150 new class implements FirstInterface, SecondInterface {}; 151 // -> FirstInterface@anonymous 152 new class {}; 153 // -> class@anonymous 154 155 The name shown above is still followed by a null byte and a unique 156 suffix. 157 . Non-absolute trait method references in trait alias adaptations are now 158 required to be unambiguous: 159 160 class X { 161 use T1, T2 { 162 func as otherFunc; 163 } 164 function func() {} 165 } 166 167 If both T1::func() and T2::func() exist, this code was previously silently 168 accepted, and func was assumed to refer to T1::func. Now it will generate a 169 fatal error instead, and either T1::func or T2::func needs to be written 170 explicitly. 171 . The signature of abstract methods defined in traits is now checked against 172 the implementing class method: 173 174 trait MyTrait { 175 abstract private function neededByTrait(): string; 176 } 177 178 class MyClass { 179 use MyTrait; 180 181 // Error, because of return type mismatch. 182 private function neededByTrait(): int { return 42; } 183 } 184 185 RFC: https://wiki.php.net/rfc/abstract_trait_method_validation 186 . Disabled functions are now treated exactly like non-existent functions. 187 Calling a disabled function will report it as unknown, and redefining a 188 disabled function is now possible. 189 . data: stream wrappers are no longer writable, which matches the documented 190 behavior. 191 . The arithmetic and bitwise operators 192 +, -, *, /, **, %, <<, >>, &, |, ^, ~, ++, -- 193 will now consistently throw a TypeError when one of the operands is an 194 array, resource or non-overloaded object. The only exception to this is the 195 array + array merge operation, which remains supported. 196 RFC: https://wiki.php.net/rfc/arithmetic_operator_type_checks 197 . Float to string casting will now always behave locale-independently. 198 RFC: https://wiki.php.net/rfc/locale_independent_float_to_string 199 . Removed support for deprecated curly braces for offset access 200 RFC: https://wiki.php.net/rfc/deprecate_curly_braces_array_access 201 . Applying the final modifier on a private method will now produce a warning 202 unless that method is the constructor. 203 RFC: https://wiki.php.net/rfc/inheritance_private_methods 204 . If an object constructor exit()s, the object destructor will no longer be 205 called. This matches the behavior when the constructor throws. 206 . Non-strict comparisons between numbers and non-numeric strings now work by 207 casting the number to string and comparing the strings. Comparisons between 208 numbers and numeric strings continue to work as before. Notably, this means 209 that `0 == "not-a-number"` is considered false now. 210 RFC: https://wiki.php.net/rfc/string_to_number_comparison 211 . Namespaced names can no longer contain whitespace: While `Foo\Bar` will be 212 recognized as a namespaced name, `Foo \ Bar` will not. Conversely, reserved 213 keywords are now permitted as namespace segments, which may also change the 214 interpretation of code: `new\x` is now the same as `constant('new\x')`, not 215 `new \x()`. 216 RFC: https://wiki.php.net/rfc/namespaced_names_as_token 217 . Nested ternaries now require explicit parentheses. 218 RFC: https://wiki.php.net/rfc/ternary_associativity 219 . debug_backtrace() and Exception::getTrace() will no longer provide 220 references to arguments. It will not be possible to change function 221 arguments through the backtrace. 222 . Numeric string handling has been altered to be more intuitive and less 223 error-prone. Trailing whitespace is now allowed in numeric strings for 224 consistency with how leading whitespace is treated. This mostly affects: 225 - The is_numeric() function 226 - String-to-string comparisons 227 - Type declarations 228 - Increment and decrement operations 229 The concept of a "leading-numeric string" has been mostly dropped; the 230 cases where this remains exist in order to ease migration. Strings which 231 emitted an E_NOTICE "A non well-formed numeric value encountered" will now 232 emit an E_WARNING "A non-numeric value encountered" and all strings which 233 emitted an E_WARNING "A non-numeric value encountered" will now throw a 234 TypeError. This mostly affects: 235 - Arithmetic operations 236 - Bitwise operations 237 This E_WARNING to TypeError change also affects the E_WARNING 238 "Illegal string offset 'string'" for illegal string offsets. The behavior 239 of explicit casts to int/float from strings has not been changed. 240 RFC: https://wiki.php.net/rfc/saner-numeric-strings 241 . Magic Methods will now have their arguments and return types checked if 242 they have them declared. The signatures should match the following list: 243 244 __call(string $name, array $arguments): mixed 245 __callStatic(string $name, array $arguments): mixed 246 __clone(): void 247 __debugInfo(): ?array 248 __get(string $name): mixed 249 __invoke(mixed $arguments): mixed 250 __isset(string $name): bool 251 __serialize(): array 252 __set(string $name, mixed $value): void 253 __set_state(array $properties): object 254 __sleep(): array 255 __unserialize(array $data): void 256 __unset(string $name): void 257 __wakeup(): void 258 259 RFC: https://wiki.php.net/rfc/magic-methods-signature 260 . call_user_func_array() array keys will now be interpreted as parameter names, 261 instead of being silently ignored. 262 263- COM: 264 . Removed the ability to import case-insensitive constants from type 265 libraries. The second argument to com_load_typelib() may no longer be false; 266 com.autoregister_casesensitive may no longer be disabled; case-insensitive 267 markers in com.typelib_file are ignored. 268 269- Curl: 270 . CURLOPT_POSTFIELDS no longer accepts objects as arrays. To interpret an 271 object as an array, perform an explicit (array) cast. The same applies to 272 other options accepting arrays as well. 273 274- Date: 275 . mktime() and gmmktime() now require at least one argument. time() can be 276 used to get the current timestamp. 277 278- dom: 279 . Remove unimplemented classes from ext/dom that had no behavior and contained 280 test data. These classes have also been removed in the latest version of DOM 281 standard: 282 283 * DOMNameList 284 * DomImplementationList 285 * DOMConfiguration 286 * DomError 287 * DomErrorHandler 288 * DOMImplementationSource 289 * DOMLocator 290 * DOMUserDataHandler 291 * DOMTypeInfo 292 293- Enchant: 294 . enchant_broker_list_dicts(), enchant_broker_describe() and 295 enchant_dict_suggest() will now return an empty array instead of null. 296 . enchant_broker_init() will now return an EnchantBroker object rather than 297 a resource. Return value checks using is_resource() should be replaced with 298 checks for `false`. 299 . enchant_broker_request_dict() and enchant_broker_request_pwl_dict() will now 300 return an EnchantDictionary object rather than a resource. Return value 301 checks using is_resource() should be replaced with checks for `false`. 302 303- Exif: 304 . Removed read_exif_data(). exif_read_data() should be used instead. 305 306- Filter: 307 . The FILTER_FLAG_SCHEME_REQUIRED and FILTER_FLAG_HOST_REQUIRED flags for the 308 FILTER_VALIDATE_URL filter have been removed. The scheme and host are (and 309 have been) always required. 310 . The INPUT_REQUEST and INPUT_SESSION source for filter_input() etc have been 311 removed. These were never implemented and their use always generated a 312 warning. 313 314- GD: 315 . The GD extension now uses a GdImage objects as the underlying data structure 316 for images, rather than resources. These objects are completely opaque, i.e. 317 they don't have any methods. Return value checks using is_resource() should 318 be replaced with checks for `false`. The imagedestroy() function no longer 319 has an effect, instead the GdImage instance is automatically destroyed if 320 it is no longer referenced. 321 . The deprecated function image2wbmp() has been removed. 322 RFC: https://wiki.php.net/rfc/image2wbmp 323 . The deprecated functions png2wbmp() and jpeg2wbmp() have been removed. 324 RFC: https://wiki.php.net/rfc/deprecate-png-jpeg-2wbmp 325 . The default $mode parameter of imagecropauto() no longer accepts -1. 326 IMG_CROP_DEFAULT should be used instead. 327 328- GMP: 329 . gmp_random() has been removed. One of gmp_random_range() or 330 gmp_random_bits() should be used instead. 331 332- Iconv: 333 . iconv() implementations which do not properly set errno in case of errors 334 are no longer supported. 335 336- IMAP: 337 . The unused default_host argument of imap_headerinfo() has been removed. 338 . The imap_header() function which is an alias of imap_headerinfo() has been removed. 339 340- Intl: 341 . The deprecated constant INTL_IDNA_VARIANT_2003 has been removed. 342 RFC: https://wiki.php.net/rfc/deprecate-and-remove-intl_idna_variant_2003 343 . The deprecated Normalizer::NONE constant has been removed. 344 . The IntlDateFormatter::RELATIVE_FULL, IntlDateFormatter::RELATIVE_LONG, 345 IntlDateFormatter::RELATIVE_MEDIUM, and IntlDateFormatter::RELATIVE_SHORT 346 constants have been added. 347 348- LDAP: 349 . The deprecated function ldap_sort has been removed. 350 . The deprecated function ldap_control_paged_result has been removed. 351 . The deprecated function ldap_control_paged_result_response has been removed. 352 . The interface of ldap_set_rebind_proc has changed; the $callback parameter 353 does not accept empty string anymore; null value shall be used instead. 354 355- Mbstring: 356 . The mbstring.func_overload directive has been removed. The related 357 MB_OVERLOAD_MAIL, MB_OVERLOAD_STRING, and MB_OVERLOAD_REGEX constants have 358 also been removed. Finally, the "func_overload" and "func_overload_list" 359 entries in mb_get_info() have been removed. 360 . mb_parse_str() can no longer be used without specifying a result array. 361 . A number of deprecated mbregex aliases have been removed. See the following 362 list for which functions should be used instead: 363 364 * mbregex_encoding() -> mb_regex_encoding() 365 * mbereg() -> mb_ereg() 366 * mberegi() -> mb_eregi() 367 * mbereg_replace() -> mb_ereg_replace() 368 * mberegi_replace() -> mb_eregi_replace() 369 * mbsplit() -> mb_split() 370 * mbereg_match() -> mb_ereg_match() 371 * mbereg_search() -> mb_ereg_search() 372 * mbereg_search_pos() -> mb_ereg_search_pos() 373 * mbereg_search_regs() -> mb_ereg_search_regs() 374 * mbereg_search_init() -> mb_ereg_search_init() 375 * mbereg_search_getregs() -> mb_ereg_search_getregs() 376 * mbereg_search_getpos() -> mb_ereg_search_getpos() 377 * mbereg_search_setpos() -> mb_ereg_search_setpos() 378 379 . The 'e' modifier for mb_ereg_replace() has been removed. 380 mb_ereg_replace_callback() should be used instead. 381 . A non-string pattern argument to mb_ereg_replace() will now be interpreted 382 as a string instead of an ASCII codepoint. The previous behavior may be 383 restored with an explicit call to chr(). 384 . The needle argument for mb_strpos(), mb_strrpos(), mb_stripos(), 385 mb_strripos(), mb_strstr(), mb_stristr(), mb_strrchr() and mb_strrichr() can 386 now be empty. 387 . The $is_hex parameter, which was not used internally, has been removed from 388 mb_decode_numericentity(). 389 . The legacy behavior of passing the encoding as the third argument instead 390 of an offset for the mb_strrpos() function has been removed; provide an 391 explicit 0 offset with the encoding as the fourth argument instead. 392 . The ISO_8859-* character encoding aliases have been replaced by ISO8859-* 393 aliases for better interoperability with the iconv extension. The mbregex 394 ISO 8859 aliases with underscores (ISO_8859_* and ISO8859_*) have also been 395 removed. 396 . mb_ereg() and mb_eregi() will now return boolean true on a successful 397 match. Previously they returned integer 1 if $matches was not passed, or 398 max(1, strlen($reg[0])) is $matches was passed. 399 400- OCI8: 401 . The OCI-Lob class is now called OCILob, and the OCI-Collection class is now 402 called OCICollection for name compliance enforced by PHP 8 arginfo 403 type annotation tooling. 404 . Several alias functions have been marked as deprecated. 405 . oci_internal_debug() and its alias ociinternaldebug() have been removed. 406 407- ODBC: 408 . odbc_connect() no longer reuses persistent connections. 409 . The unused flags parameter of odbc_exec() has been removed. 410 411- OpenSSL: 412 . openssl_x509_read() and openssl_csr_sign() will now return an 413 OpenSSLCertificate object rather than a resource. Return value checks using 414 is_resource() should be replaced with checks for `false`. 415 . The openssl_x509_free() function is deprecated and no longer has an effect, 416 instead the OpenSSLCertificate instance is automatically destroyed if it is no 417 longer referenced. 418 . openssl_csr_new() will now return an OpenSSLCertificateSigningRequest object 419 rather than a resource. Return value checks using is_resource() should be 420 replaced with checks for `false`. 421 . openssl_pkey_new() will now return an OpenSSLAsymmetricKey object rather than a 422 resource. Return value checks using is_resource() should be replaced with 423 checks for `false`. 424 . The openssl_pkey_free() function is deprecated and no longer has an effect, 425 instead the OpenSSLAsymmetricKey instance is automatically destroyed if it is no 426 longer referenced. 427 . openssl_seal() and openssl_open() now require $method to be passed, as the 428 previous default of "RC4" is considered insecure. 429 430- PCRE: 431 . When passing invalid escape sequences they are no longer interpreted as 432 literals. This behavior previously required the X modifier - which is 433 now ignored. 434 435- PDO: 436 . The default error handling mode has been changed from "silent" to 437 "exceptions". See https://www.php.net/manual/en/pdo.error-handling.php 438 for details of behavior changes and how to explicitly set this attribute. 439 RFC: https://wiki.php.net/rfc/pdo_default_errmode 440 . The signatures of some PDO methods have changed: 441 442 PDO::query( 443 string $statement, ?int $fetch_mode = null, ...$fetch_mode_args) 444 PDOStatement::setFetchMode(int $mode, ...$params) 445 446- PDO MySQL: 447 . PDO::inTransaction() now reports the actual transaction state of the 448 connection, rather than an approximation maintained by PDO. If a query that 449 is subject to "implicit commit" is executed, PDO::inTransaction() will 450 subsequently return false, as a transaction is no longer active. 451 452- PDO_ODBC: 453 . The php.ini directive pdo_odbc.db2_instance_name has been removed 454 455- pgsql: 456 . The deprecated pg_connect() syntax using multiple parameters instead of a 457 connection string is no longer supported. 458 . The deprecated pg_lo_import() and pg_lo_export() signature that passes the 459 connection as the last argument is no longer supported. The connection 460 should be passed as first argument instead. 461 . pg_fetch_all() will now return an empty array instead of false for result 462 sets with zero rows. 463 464- Phar: 465 . Metadata associated with a phar will no longer be automatically unserialized, 466 to fix potential security vulnerabilities due to object instantiation, autoloading, etc. 467 RFC: https://wiki.php.net/rfc/phar_stop_autoloading_metadata 468 469- Reflection: 470 . The method signatures 471 472 ReflectionClass::newInstance($args) 473 ReflectionFunction::invoke($args) 474 ReflectionMethod::invoke($object, $args) 475 476 have been changed to: 477 478 ReflectionClass::newInstance(...$args) 479 ReflectionFunction::invoke(...$args) 480 ReflectionMethod::invoke($object, ...$args) 481 482 Code that must be compatible with both PHP 7 and PHP 8 can use the following 483 signatures to be compatible with both versions: 484 485 ReflectionClass::newInstance($arg = null, ...$args) 486 ReflectionFunction::invoke($arg = null, ...$args) 487 ReflectionMethod::invoke($object, $arg = null, ...$args) 488 489 . The ReflectionType::__toString() method will now return a complete debug 490 representation of the type, and is no longer deprecated. In particular the 491 result will include a nullability indicator for nullable types. The format 492 of the return value is not stable and may change between PHP versions. 493 . Reflection export() methods have been removed. 494 . The following methods can now return information about default values of 495 parameters of internal functions: 496 ReflectionParameter::isDefaultValueAvailable() 497 ReflectionParameter::getDefaultValue() 498 ReflectionParameter::isDefaultValueConstant() 499 ReflectionParameter::getDefaultValueConstantName() 500 . ReflectionMethod::isConstructor() and ReflectionMethod::isDestructor() now 501 also return true for `__construct` and `__destruct` methods of interfaces. 502 Previously, this would only be true for methods of classes and traits. 503 . ReflectionType::isBuiltin() method has been moved to ReflectionNamedType. 504 ReflectionUnionType does not have it. 505 506- Sockets: 507 . The deprecated AI_IDN_ALLOW_UNASSIGNED and AI_IDN_USE_STD3_ASCII_RULES 508 flags for socket_addrinfo_lookup() have been removed. 509 . socket_create(), socket_create_listen(), socket_accept(), 510 socket_import_stream(), socket_addrinfo_connect(), socket_addrinfo_bind(), 511 and socket_wsaprotocol_info_import() will now return a Socket object rather 512 than a resource. Return value checks using is_resource() should be replaced 513 with checks for `false`. 514 . socket_addrinfo_lookup() will now return an array of AddressInfo objects 515 rather than resources. 516 517- SPL: 518 . SplFileObject::fgetss() has been removed. 519 . SplFileObject::seek() now always seeks to the beginning of the line. 520 Previously, positions >=1 sought to the beginning of the next line. 521 . SplHeap::compare($a, $b) now specifies a method signature. Inheriting 522 classes implementing this method will now have to use a compatible 523 method signature. 524 . SplDoublyLinkedList::push() now returns void instead of true 525 . SplDoublyLinkedList::unshift() now returns void instead of true 526 . SplQueue::enqueue() now returns void instead of true 527 . spl_autoload_register() will now always throw a TypeError on invalid 528 arguments, therefore the second argument $do_throw is ignored and a 529 notice will be emitted if it is set to false. 530 . SplFixedArray is now an IteratorAggregate and not an Iterator. 531 SplFixedArray::rewind(), ::current(), ::key(), ::next(), and ::valid() 532 have been removed. In their place, SplFixedArray::getIterator() has been 533 added. Any code which uses explicit iteration over SplFixedArray must now 534 obtain an Iterator through SplFixedArray::getIterator(). This means that 535 SplFixedArray is now safe to use in nested loops. 536 537- Standard: 538 . assert() will no longer evaluate string arguments, instead they will be 539 treated like any other argument. assert($a == $b) should be used instead of 540 assert('$a == $b'). The assert.quiet_eval ini directive and 541 ASSERT_QUIET_EVAL constants have also been removed, as they would no longer 542 have any effect. 543 . parse_str() can no longer be used without specifying a result array. 544 . fgetss() has been removed. 545 . The string.strip_tags filter has been removed. 546 . The needle argument of strpos(), strrpos(), stripos(), strripos(), strstr(), 547 strchr(), strrchr(), and stristr() will now always be interpreted as a 548 string. Previously non-string needles were interpreted as an ASCII code 549 point. An explicit call to chr() can be used to restore the previous 550 behavior. 551 . The needle argument for strpos(), strrpos(), stripos(), strripos(), 552 strstr(), stristr() and strrchr() can now be empty. 553 . The length argument for substr(), substr_count(), substr_compare(), and 554 iconv_substr() can now be null. Null values will behave as if no length 555 argument was provided and will therefore return the remainder of the string 556 instead of an empty string. 557 . The length argument for array_splice() can now be null. Null values will 558 behave identically to omitting the argument, thus removing everything from 559 the 'offset' to the end of the array. 560 . The args argument of vsprintf(), vfprintf(), and vprintf() must now be an 561 array. Previously any type was accepted. 562 . The 'salt' option of password_hash() is no longer supported. If the 'salt' 563 option is used a warning is generated, the provided salt is ignored, and a 564 generated salt is used instead. 565 . The quotemeta() function will now return an empty string if an empty string 566 was passed. Previously false was returned. 567 . hebrevc() has been removed. 568 . convert_cyr_string() has been removed. 569 . money_format() has been removed. 570 . ezmlm_hash() has been removed. 571 . restore_include_path() has been removed. 572 . get_magic_quotes_gpc() and get_magic_quotes_runtime() has been removed. 573 . FILTER_SANITIZE_MAGIC_QUOTES has been removed. 574 . Calling implode() with parameters in a reverse order ($pieces, $glue) is no 575 longer supported. 576 . parse_url() will now distinguish absent and empty queries and fragments: 577 578 http://example.com/foo => query = null, fragment = null 579 http://example.com/foo? => query = "", fragment = null 580 http://example.com/foo# => query = null, fragment = "" 581 http://example.com/foo?# => query = "", fragment = "" 582 583 Previously all cases resulted in query and fragment being null. 584 . var_dump() and debug_zval_dump() will now print floating-point numbers 585 using serialize_precision rather than precision. In a default configuration, 586 this means that floating-point numbers are now printed with full accuracy 587 by these debugging functions. 588 . If the array returned by __sleep() contains non-existing properties, these 589 are now silently ignored. Previously, such properties would have been 590 serialized as if they had the value NULL. 591 . The default locale on startup is now always "C". No locales are inherited 592 from the environment by default. Previously, LC_ALL was set to "C", while 593 LC_CTYPE was inherited from the environment. However, some functions did not 594 respect the inherited locale without an explicit setlocale() call. An 595 explicit setlocale() call is now always required if you wish to change any 596 locale component from the default. 597 . Removed deprecated DES fallback in crypt(). If an unknown salt format is 598 passed to crypt(), the function will fail with *0 instead of falling back 599 to a weak DES hash now. 600 . Specifying out of range rounds for sha256/sha512 crypt() will now fail with 601 *0 instead of clamping to the closest limit. This matches glibc behavior. 602 . The result of sorting functions may have changed, if the array contains 603 elements that compare as equal. 604 . Sort comparison functions that return true or false will now throw a 605 deprecation warning, and should be replaced with an implementation 606 that returns an integer less than, equal to, or greater than zero. 607 608 // Replace 609 usort($array, fn($a, $b) => $a > $b); 610 // With 611 usort($array, fn($a, $b) => $a <=> $b); 612 613 . Any functions accepting callbacks that are not explicitly specified to 614 accept parameters by reference will now warn if a callback with reference 615 parameters is used. Examples include array_filter() and array_reduce(). 616 This was already the case for most, but not all, functions previously. 617 . The HTTP stream wrapper as used by functions like file_get_contents() 618 now advertises HTTP/1.1 rather than HTTP/1.0 by default. This does not 619 change the behavior of the client, but may cause servers to respond 620 differently. To retain the old behavior, set the 'protocol_version' 621 stream context option, e.g. 622 623 $ctx = stream_context_create(['http' => ['protocol_version' => '1.0']]); 624 echo file_get_contents('http://example.org', false, $ctx); 625 . Calling crypt() without an explicit salt is no longer supported. If you 626 would like to produce a strong hash with an auto-generated salt, use 627 password_hash() instead. 628 . substr(), mb_substr(), iconv_substr() and grapheme_substr() now consistently 629 clamp out-of-bounds offsets to the string boundary. Previously, false was 630 returned instead of the empty string in some cases. 631 . Populating $http_response_header variable by the HTTP stream wrapper 632 doesn't force rebuilding of symbol table anymore. 633 634- Sysvmsg: 635 . msg_get_queue() will now return an SysvMessageQueue object rather than a 636 resource. Return value checks using is_resource() should be replaced with 637 checks for `false`. 638 639- Sysvsem: 640 . sem_get() will now return an SysvSemaphore object rather than a resource. 641 Return value checks using is_resource() should be replaced with checks 642 for `false`. 643 . The $auto_release parameter of sem_get() was changed to accept bool values 644 rather than int. 645 646- Sysvshm: 647 . shm_attach() will now return an SysvSharedMemory object rather than a resource. 648 Return value checks using is_resource() should be replaced with checks 649 for `false`. 650 651- tidy: 652 . The $use_include_path parameter, which was not used internally, has been 653 removed from tidy_repair_string(). 654 . tidy::repairString() and tidy::repairFile() became static methods 655 656- Tokenizer: 657 . T_COMMENT tokens will no longer include a trailing newline. The newline will 658 instead be part of a following T_WHITESPACE token. It should be noted that 659 T_COMMENT is not always followed by whitespace, it may also be followed by 660 T_CLOSE_TAG or end-of-file. 661 . Namespaced names are now represented using the T_NAME_QUALIFIED (Foo\Bar), 662 T_NAME_FULLY_QUALIFIED (\Foo\Bar) and T_NAME_RELATIVE (namespace\Foo\Bar) 663 tokens. T_NS_SEPARATOR is only used for standalone namespace separators, 664 and only syntactially valid in conjunction with group use declarations. 665 RFC: https://wiki.php.net/rfc/namespaced_names_as_token 666 667- XML: 668 . xml_parser_create(_ns) will now return an XMLParser object rather than a 669 resource. Return value checks using is_resource() should be replaced with 670 checks for `false`. The xml_parser_free() function no longer has an effect, 671 instead the XMLParser instance is automatically destroyed if it is no longer 672 referenced. 673 674- XMLReader: 675 . XMLReader::open() and XMLReader::xml() are now static methods. They still 676 can be called dynamically, though, but inheriting classes need to declare 677 them as static if they override these methods. 678 679- XMLWriter: 680 . The XMLWriter functions now accept and return, respectively, XMLWriter 681 objects instead of resources. 682 683- Zip: 684 . ZipArchive::OPSYS_Z_CPM has been removed (this name was a typo). Use 685 ZipArchive::OPSYS_CPM instead. 686 687- Zlib: 688 . gzgetss() has been removed. 689 . inflate_init() will now return an InflateContext object rather than a 690 resource. Return value checks using is_resource() should be replaced with 691 checks for `false`. 692 . deflate_init() will now return a DeflateContext object rather than a 693 resource. Return value checks using is_resource() should be replaced with 694 checks for `false`. 695 . zlib.output_compression is no longer automatically disabled for 696 Content-Type: image/*. 697 698======================================== 6992. New Features 700======================================== 701 702- Core: 703 . Added support for union types. 704 RFC: https://wiki.php.net/rfc/union_types_v2 705 . Added WeakMap. 706 RFC: https://wiki.php.net/rfc/weak_maps 707 . Added ValueError class. 708 . Any number of function parameters may now be replaced by a variadic 709 argument, as long as the types are compatible. For example, the following 710 code is now allowed: 711 712 class A { 713 public function method(int $many, string $parameters, $here) {} 714 } 715 class B extends A { 716 public function method(...$everything) {} 717 } 718 . "static" (as in "late static binding") can now be used as a return type: 719 720 class Test { 721 public function create(): static { 722 return new static(); 723 } 724 } 725 726 RFC: https://wiki.php.net/rfc/static_return_type 727 . It is now possible to fetch the class name of an object using 728 `$object::class`. The result is the same as `get_class($object)`. 729 RFC: https://wiki.php.net/rfc/class_name_literal_on_object 730 . New and instanceof can now be used with arbitrary expressions, using 731 `new (expression)(...$args)` and `$obj instanceof (expression)`. 732 RFC: https://wiki.php.net/rfc/variable_syntax_tweaks 733 . Some consistency fixes to variable syntax have been applied, for example 734 writing `Foo::BAR::$baz` is now allowed. 735 RFC: https://wiki.php.net/rfc/variable_syntax_tweaks 736 . Added Stringable interface, which is automatically implemented if a class 737 defines a __toString() method. 738 RFC: https://wiki.php.net/rfc/stringable 739 . Traits can now define abstract private methods. 740 RFC: https://wiki.php.net/rfc/abstract_trait_method_validation 741 . `throw` can now be used as an expression. 742 RFC: https://wiki.php.net/rfc/throw_expression 743 . An optional trailing comma is now allowed in parameter lists. 744 RFC: https://wiki.php.net/rfc/trailing_comma_in_parameter_list 745 . It is now possible to write `catch (Exception)` to catch an exception 746 without storing it in a variable. 747 RFC: https://wiki.php.net/rfc/non-capturing_catches 748 . Added support for mixed type 749 RFC: https://wiki.php.net/rfc/mixed_type_v2 750 . Added support for Attributes 751 RFC: https://wiki.php.net/rfc/attributes_v2 752 RFC: https://wiki.php.net/rfc/attribute_amendments 753 RFC: https://wiki.php.net/rfc/shorter_attribute_syntax 754 RFC: https://wiki.php.net/rfc/shorter_attribute_syntax_change 755 . Added support for constructor property promotion (declaring properties in 756 the constructor signature). 757 RFC: https://wiki.php.net/rfc/constructor_promotion 758 . Added support for `match` expression. 759 RFC: https://wiki.php.net/rfc/match_expression_v2 760 . Private methods declared on a parent class no longer enforce any 761 inheritance rules on the methods of a child class. (with the exception of 762 final private constructors) 763 RFC: https://wiki.php.net/rfc/inheritance_private_methods 764 . Added support for nullsafe operator (`?->`). 765 RFC: https://wiki.php.net/rfc/nullsafe_operator 766 . Added support for named arguments. 767 RFC: https://wiki.php.net/rfc/named_params 768 769- Date: 770 . Added DateTime::createFromInterface() and 771 DateTimeImmutable::createFromInterface(). 772 . Added the DateTime format specifier "p" which is the same as "P" but 773 returning "Z" for UTC. 774 775- Dom: 776 . Introduce DOMParentNode and DOMChildNode with new traversal and 777 manipulation APIs. 778 RFC: https://wiki.php.net/rfc/dom_living_standard_api 779 780- Enchant: 781 . enchant_dict_add() 782 . enchant_dict_is_added() 783 . LIBENCHANT_VERSION macro 784 785- FPM: 786 . Added a new option pm.status_listen that allows getting status from 787 different endpoint (e.g. port or UDS file) which is useful for getting 788 status when all children are busy with serving long running requests. 789 790- Hash: 791 . HashContext objects can now be serialized. 792 793- Opcache: 794 . If the opcache.record_warnings ini setting is enabled, opcache will record 795 compile-time warnings and replay them on the next include, even if it is 796 served from cache. 797 798- OpenSSL: 799 . Added Cryptographic Message Syntax (CMS) (RFC 5652) support composed of 800 functions for encryption, decryption, signing, verifying and reading. The 801 API is similar to the API for PKCS #7 functions with an addition of new 802 encoding constants: OPENSSL_ENCODING_DER, OPENSSL_ENCODING_SMIME and 803 OPENSSL_ENCODING_PEM. 804 805- Standard: 806 . printf() and friends now support the %h and %H format specifiers. These 807 are the same as %g and %G, but always use "." as the decimal separator, 808 rather than determining it through the LC_NUMERIC locale. 809 . printf() and friends now support using "*" as width or precision, in which 810 case the width/precision is passed as an argument to printf. This also 811 allows using precision -1 with %g, %G, %h and %H. For example, the following 812 code can be used to reproduce PHP's default floating point formatting: 813 814 printf("%.*H", (int) ini_get("precision"), $float); 815 printf("%.*H", (int) ini_get("serialize_precision"), $float); 816 817 . proc_open() now supports pseudo-terminal (PTY) descriptors. The following 818 attaches stdin, stdout and stderr to the same PTY: 819 820 $proc = proc_open($command, [['pty'], ['pty'], ['pty']], $pipes); 821 822 . proc_open() now supports socket pair descriptors. The following attaches 823 a distinct socket pair to stdin, stdout and stderr: 824 825 $proc = proc_open( 826 $command, [['socket'], ['socket'], ['socket']], $pipes); 827 828 Unlike pipes, sockets do not suffer from blocking I/O issues on Windows. 829 However, not all programs may work correctly with stdio sockets. 830 . Sorting functions are now stable, which means that equal-comparing elements 831 will retain their original order. 832 RFC: https://wiki.php.net/rfc/stable_sorting 833 . array_diff(), array_intersect() and their variations can now be used with 834 a single array as argument. This means that usages like the following are 835 now possible: 836 837 // OK even if $excludes is empty. 838 array_diff($array, ...$excludes); 839 // OK even if $arrays only contains a single array. 840 array_intersect(...$arrays); 841 . The $flag parameter of ob_implicit_flush() was changed to accept bool 842 values rather than int. 843 844- Zip: 845 . Extension updated to version 1.19.1 846 . New ZipArchive::lastId property to get index value of last added entry. 847 . Error can be checked after an archive is closed using ZipArchive::status, 848 ZipArchive::statusSys properties or ZipArchive::getStatusString() method. 849 . The remove_path option of ZipArchive::addGlob() and ::addPattern() is now 850 treated as arbitrary string prefix (for consistency with the add_path 851 option), whereas formerly it was treated as directory name. 852 . Optional compression / encryption features are listed in phpinfo. 853 854======================================== 8553. Changes in SAPI modules 856======================================== 857 858- Apache: 859 . The PHP module has been renamed from php7_module to php_module. 860 861======================================== 8624. Deprecated Functionality 863======================================== 864 865- Core: 866 . Declaring a required parameter after an optional one is deprecated. As an 867 exception, declaring a parameter of the form "Type $param = null" before 868 a required one continues to be allowed, because this pattern was sometimes 869 used to achieve nullable types in older PHP versions. 870 871 function test($a = [], $b) {} // Deprecated 872 function test(Foo $a = null, $b) {} // Allowed 873 . Calling get_defined_functions() with $exclude_disabled explicitly set to 874 false is deprecated. get_defined_functions() will never include disabled 875 functions. 876 877- Enchant: 878 . enchant_broker_set_dict_path and enchant_broker_get_dict_path 879 not available in libenchant < 1.5 nor in libenchant-2 880 . enchant_dict_add_to_personal, use enchant_dict_add instead 881 . enchant_dict_is_in_session, use enchant_dict_is_added instead 882 . enchant_broker_free and enchant_broker_free_dict, unset the object instead 883 . ENCHANT_MYSPELL and ENCHANT_ISPELL constants 884 885- LibXML: 886 . libxml_disable_entity_loader() has been deprecated. As libxml 2.9.0 is now 887 required, external entity loading is guaranteed to be disabled by default, 888 and this function is no longer needed to protect against XXE attacks. 889 890- PGSQL / PDO PGSQL: 891 . The constant PGSQL_LIBPQ_VERSION_STR has now the same value as 892 PGSQL_LIBPQ_VERSION, and thus is deprecated. 893 . Function aliases in the pgsql extension have been deprecated. 894 895- Zip: 896 . Using empty file as ZipArchive is deprecated. Libzip 1.6.0 897 do not accept empty files as valid zip archives any longer. 898 Existing workaround will be removed in next version. 899 . The procedural API of Zip is deprecated. Use ZipArchive instead. 900 901- Reflection: 902 . ReflectionFunction::isDisabled() is deprecated, as it is no longer possible 903 to create a ReflectionFunction for a disabled function. This method now 904 always returns false. 905 . ReflectionParameter::getClass(), ReflectionParameter::isArray(), and 906 ReflectionParameter::isCallable() are deprecated. 907 ReflectionParameter::getType() and the ReflectionType APIs should be used 908 instead. 909 910======================================== 9115. Changed Functions 912======================================== 913 914- Reflection: 915 . ReflectionClass::getConstants and ReflectionClass::getReflectionConstants results 916 can be now filtered via a new parameter `$filter`. 3 new constants were added to 917 be used with it: 918 919 ReflectionClassConstant::IS_PUBLIC 920 ReflectionClassConstant::IS_PROTECTED 921 ReflectionClassConstant::IS_PRIVATE 922 923- Zip 924 . ZipArchive::addGlob and ZipArchive::addPattern methods accept more 925 values in the "options" array argument: 926 . flags 927 . comp_method 928 . comp_flags 929 . env_method 930 . enc_password 931 . ZipArchive::addEmptyDir, ZipArchive::addFile and aZipArchive::addFromString 932 methods have a new "flags" argument. This allows managing name encoding 933 (ZipArchive::FL_ENC_*) and entry replacement (ZipArchive::FL_OVERWRITE) 934 . ZipArchive::extractTo now restore file modification time. 935 936======================================== 9376. New Functions 938======================================== 939 940- Core: 941 . Added get_resource_id($resource) function, which returns the same value as 942 (int) $resource. It provides the same functionality under a clearer API. 943 944- LDAP: 945 . Added ldap_count_references(), which returns the number of reference 946 messages in a search result. 947 948- OpenSSL: 949 . Added openssl_cms_encrypt() encrypts the message in the file with the 950 certificates and outputs the result to the supplied file. 951 . Added openssl_cms_decrypt() that decrypts the S/MIME message in the file 952 and outputs the results to the supplied file. 953 . Added openssl_cms_read() that exports the CMS file to an array of PEM 954 certificates. 955 . Added openssl_cms_sign() that signs the MIME message in the file with 956 a cert and key and output the result to the supplied file. 957 . Added openssl_cms_verify() that verifies that the data block is intact, 958 the signer is who they say they are, and returns the certs of the signers. 959 960- PCRE: 961 . Added preg_last_error_msg(), which returns a human-readable message for 962 the last PCRE error. It complements preg_last_error(), which returns an 963 integer enum instead. 964 965- SQLite3: 966 . Add SQLite3::setAuthorizer() and respective class constants to set a 967 userland callback that will be used to authorize or not an action on the 968 database. 969 PR: https://github.com/php/php-src/pull/4797 970 971- Standard: 972 . Added 973 974 str_contains(string $haystack, string $needle): bool 975 str_starts_with(string $haystack, string $needle): bool 976 str_ends_with(string $haystack, string $needle): bool 977 978 functions, which check whether $haystack contains, starts with or ends with 979 $needle. 980 RFC: https://wiki.php.net/rfc/str_contains 981 RFC: https://wiki.php.net/rfc/add_str_starts_with_and_ends_with_functions 982 . Added fdiv() function, which performs a floating-point division under 983 IEEE 754 semantics. Division by zero is considered well-defined and 984 will return one of Inf, -Inf or NaN. 985 . Added get_debug_type() function, which returns a type useful for error 986 messages. Unlike gettype(), it uses canonical type names, returns class 987 names for objects, and indicates the resource type for resources. 988 RFC: https://wiki.php.net/rfc/get_debug_type 989 990- Zip: 991 . ZipArchive::setMtimeName and ZipArchive::setMtimeIndex to set the 992 modification time of an entry. 993 . ZipArchive::registerProgressCallback to provide updates during archive close. 994 . ZipArchive::registerCancelCallback to allow cancellation during archive close. 995 . ZipArchive::replaceFile to replace an entry content. 996 . ZipArchive::isCompressionMethodSupported to check optional compression 997 features. 998 . ZipArchive::isEncryptionMethodSupported to check optional encryption 999 features. 1000 1001======================================== 10027. New Classes and Interfaces 1003======================================== 1004 1005- Tokenizer: 1006 . The new PhpToken class adds an object-based interface to the tokenizer. 1007 It provides a more uniform and ergonomic representation, while being more 1008 memory efficient and faster. 1009 RFC: https://wiki.php.net/rfc/token_as_object 1010 1011======================================== 10128. Removed Extensions and SAPIs 1013======================================== 1014 1015- XML-RPC: 1016 . The xmlrpc extension has been unbundled and moved to PECL. 1017 RFC: https://wiki.php.net/rfc/unbundle_xmlprc 1018 1019======================================== 10209. Other Changes to Extensions 1021======================================== 1022 1023- CURL: 1024 . The CURL extension now requires at least libcurl 7.29.0. 1025 . curl_init() will now return a CurlHandle object rather than a resource. 1026 Return value checks using is_resource() should be replaced with 1027 checks for `false`. The curl_close() function no longer has an effect, 1028 instead the CurlHandle instance is automatically destroyed if it is no 1029 longer referenced. 1030 . curl_multi_init() will now return a CurlMultiHandle object rather than a 1031 resource. Return value checks using is_resource() should be replaced with 1032 checks for `false`. The curl_multi_close() function no longer has an effect, 1033 instead the CurlMultiHandle instance is automatically destroyed if it is no 1034 longer referenced. 1035 . curl_share_init() will now return a CurlShareHandle object rather than a 1036 resource. Return value checks using is_resource() should be replaced with 1037 checks for `false`. The curl_share_close() function no longer has an effect, 1038 instead the CurlShareHandle instance is automatically destroyed if it is no 1039 longer referenced. 1040 . The deprecated parameter `$version` of curl_version() has been removed. 1041 1042- Date: 1043 . DatePeriod now implements IteratorAggregate (instead of Traversable). 1044 1045- DOM: 1046 . DOMNamedNodeMap now implements IteratorAggregate (instead of Traversable). 1047 . DOMNodeList now implements IteratorAggregate (instead of Traversable). 1048 1049- Intl: 1050 . IntlBreakIterator now implements IteratorAggregate (instead of Traversable). 1051 . ResourceBundle now implements IteratorAggregate (instead of Traversable). 1052 1053- Enchant: 1054 . The enchant extension now uses libenchant-2 by default when available. 1055 libenchant version 1 is still supported but is deprecated and could 1056 be removed in the future. 1057 1058- GD: 1059 . The $num_points parameter of imagepolygon(), imageopenpolygon() and 1060 imagefilledpolygon() is now optional, i.e. these functions may be called 1061 with either 3 or 4 arguments. If the arguments is omitted, it is calculated 1062 as count($points)/2. 1063 . The function imagegetinterpolation() to get the current interpolation method 1064 has been added. 1065 1066- JSON: 1067 . The JSON extension cannot be disabled anymore and is always an integral part 1068 of any PHP build, similar to the date extension. 1069 1070- MBString: 1071 . The Unicode data tables have been updated to version 13.0.0. 1072 1073- PDO: 1074 . PDOStatement now implements IteratorAggregate (instead of Traversable). 1075 1076- LibXML: 1077 . The minimum required libxml version is now 2.9.0. This means that external 1078 entity loading is now guaranteed to be disabled by default, and no extra 1079 steps need to be taken to protect against XXE attacks. 1080 1081- MySQLi / PDO MySQL: 1082 . When mysqlnd is not used (which is the default and recommended option), 1083 the minimum supported libmysqlclient version is now 5.5. 1084 . mysqli_result now implements IteratorAggregate (instead of Traversable). 1085 1086- PGSQL / PDO PGSQL: 1087 . The PGSQL and PDO PGSQL extensions now require at least libpq 9.1. 1088 1089- Readline: 1090 . Calling readline_completion_function() before the interactive prompt starts 1091 (e.g. in auto_prepend_file) will now override the default interactive prompt 1092 completion function. Previously, readline_completion_function() only worked 1093 when called after starting the interactive prompt. 1094 1095- SimpleXML: 1096 . SimpleXMLElement now implements RecursiveIterator and absorbed the 1097 functionality of SimpleXMLIterator. SimpleXMLIterator is an empty extension 1098 of SimpleXMLElement. 1099 1100- Shmop: 1101 . shmop_open() will now return a Shmop object rather than a resource. Return 1102 value checks using is_resource() should be replaced with checks for `false`. 1103 The shmop_close() function no longer has an effect, and is deprecated; 1104 instead the Shmop instance is automatically destroyed if it is no longer 1105 referenced. 1106 1107======================================== 110810. New Global Constants 1109======================================== 1110 1111- Filter: 1112 . FILTER_VALIDATE_BOOL has been added as an alias for FILTER_VALIDATE_BOOLEAN. 1113 The new name is preferred, as it uses the canonical type name. 1114 1115======================================== 111611. Changes to INI File Handling 1117======================================== 1118 1119- zend.exception_string_param_max_len 1120 . New INI directive to set the maximum string length in an argument of a 1121 stringified stack strace. 1122 1123- com.dotnet_version 1124 . New INI directive to choose the version of the .NET framework to use for 1125 dotnet objects. 1126 1127======================================== 112812. Windows Support 1129======================================== 1130 1131- Standard: 1132 . Program execution functions (proc_open(), exec(), popen() etc.) using the 1133 shell now consistently execute `%comspec% /s /c "$commandline"`, which has 1134 the same effect as executing `$commandline` (without additional quotes). 1135 1136- GD: 1137 . php_gd2.dll has been renamed to php_gd.dll. 1138 1139- php-test-pack: 1140 . The test runner has been renamed from run-test.php to run-tests.php, to 1141 match its name in php-src. 1142 1143======================================== 114413. Other Changes 1145======================================== 1146 1147- EBCDIC targets are no longer supported, though it's unlikely that they were 1148 still working in the first place. 1149 1150======================================== 115114. Performance Improvements 1152======================================== 1153 1154- A Just-In-Time (JIT) compiler has been added to the opcache extension. 1155- array_slice() on an array without gaps will no longer scan the whole array to 1156 find the start offset. This may significantly reduce the runtime of the 1157 function with large offsets and small lengths. 1158- strtolower() now uses a SIMD implementation when using the "C" LC_CTYPE 1159 locale (which is the default). 1160