xref: /PHP-7.4/UPGRADING (revision b5cb999e)
1PHP 7.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. Migration to pkg-config
1614. Other Changes
1715. Performance Improvements
18
19
20========================================
211. Backward Incompatible Changes
22========================================
23
24- Core:
25  . Trying to use values of type null, bool, int, float or resource as an
26    array (such as $null["key"]) will now generate a notice. This does not
27    affect array accesses performed by list().
28    RFC: https://wiki.php.net/rfc/notice-for-non-valid-array-container
29  . get_declared_classes() no longer returns anonymous classes that haven't
30    been instantiated yet.
31  . "fn" is now a reserved keyword. In particular, it can no longer be used as a
32    function or class name. It can still be used as a method or class constant
33    name.
34  . Passing the result of a (non-reference) list() assignment by reference is
35    consistently disallowed now. Previously this worked if the right-hand side
36    was a simple (CV) variable and did not occur as part of the list().
37  . `<?php` at the end of the file (without trailing newline) will now be
38    interpreted as an opening PHP tag. Previously it was interpreted either as
39    `<? php` and resulted in a syntax error (with short_open_tag=1) or was
40    interpreted as a literal `<?php` string (with short_open_tag=0).
41  . When using include/require on a stream, stream_set_option() will be invoked
42    with the STREAM_OPTION_READ_BUFFER option. Custom stream wrapper
43    implementations may need to implement the stream_set_option() method to
44    avoid a warning (always returning false is a sufficient implementation).
45  . The "creating default object from empty value" warning is now consistently
46    thrown if a falsy value is promoted into an stdClass object. Previously some
47    cases like `$null->prop[0] = $val` missed this warning.
48  . Previously get_declared_classes() always returned parent classes before
49    child classes. This is no longer the case. No particular order is guaranteed
50    for the get_declared_classes() return value.
51
52- BCMath:
53  . BCMath functions will now warn if a non well-formed number is passed, such
54    as "32foo". The argument will be interpreted as zero (as before).
55
56- Curl:
57  . Attempting to serialize a CURLFile class will now generate an exception.
58    Previously the exception was only thrown on unserialization.
59  . Using CURLPIPE_HTTP1 is deprecated, and is no longer supported as of cURL
60    7.62.0.
61  . The $version parameter of curl_version() is deprecated. If any value not
62    equal to the default CURLVERSION_NOW is passed, a warning is raised and the
63    parameter is ignored.
64
65- Date:
66  . Calling var_dump() or similar on a DateTime(Immutable) instance will no
67    longer leave behind accessible properties on the object.
68  . Comparison of DateInterval objects (using ==, < and so on) will now generate
69    a warning and always return false. Previously all DateInterval objects were
70    considered equal, unless they had properties.
71
72DOM:
73  . As of PHP 7.4.4, the value of the $childNodes property of DOMDocument,
74    DOMNode, DOMProcessingInstruction, DOMComment, DOMText, DOMCdataSection and
75    DOMNotation is now an empty DOMNodeList instead of NULL, according to the
76    W3C and WHATWG standards and the PHP manual.
77
78- Intl:
79  . The default parameter value of idn_to_ascii() and idn_to_utf8() is now
80    INTL_IDNA_VARIANT_UTS46 instead of the deprecated INTL_IDNA_VARIANT_2003.
81
82- MySQLi:
83  . The embedded server functionality has been removed. It was broken since
84    at least PHP 7.0.
85  . The undocumented mysqli::$stat property has been removed in favor of
86    mysqli::stat().
87
88- Openssl:
89  . The openssl_random_pseudo_bytes() function will now throw an exception in
90    error situations, similar to random_bytes(). In particular, an Error is
91    thrown if the number of requested bytes is less than *or equal to* zero,
92    and an Exception is thrown if sufficient randomness cannot be gathered.
93    The $crypto_strong output argument is guaranteed to always be true if the
94    function does not throw, so explicitly checking it is not necessary.
95    RFC: http://php.net/manual/de/function.openssl-random-pseudo-bytes.php
96
97- Pcntl:
98  . The $restart_syscalls flag for pcntl_signal() will now be respected for
99    SIGALARM. Previously it was hardcoded to false. To reduce the backwards
100    compatibility impact, the default for SIGALARM will remain false however.
101
102- PCRE:
103  . When PREG_UNMATCHED_AS_NULL mode is used, trailing unmatched capturing
104    groups will now also be set to null (or [null, -1] if offset capture is
105    enabled). This means that the size of the $matches will always be the same.
106
107- PEAR:
108  . Installation of PEAR (including PECL) is no longer enabled by default. It
109    can be explicitly enabled using --with-pear. This option is deprecated and
110    may be removed in the future.
111
112- PDO:
113  . Attempting to serialize a PDO or PDOStatement instance will now generate
114    an Exception rather than a PDOException, consistent with other internal
115    classes which do not support serialization.
116
117- Reflection:
118  . Reflection objects will now generate an exception if an attempt is made
119    to serialize them. Serialization for reflection objects was never
120    supported and resulted in corrupted reflection objects. It has been
121    explicitly prohibited now.
122  . The signature of the ReflectionMethod::getClosure() method changed to
123    account for existing behavior with static methods:
124        Before: ReflectionMethod::getClosure($object)
125        After: ReflectionMethod::getClosure($object = null)
126    The new signature is also (LSP) compatible with older PHP versions.
127
128- SAPI:
129  . Starting with 7.4.11, incoming cookie names are not url-decoded. This was never
130    required by the standard, outgoing cookie names aren't encoded and this leads
131    to security issues (CVE-2020-7070).
132
133- SPL:
134  . Calling get_object_vars() on an ArrayObject instance will now always return
135    the properties of the ArrayObject itself (or a subclass). Previously it
136    returned the values of the wrapped array/object unless the STD_PROP_LIST
137    flag was specified. Other affected operations are:
138
139     * ReflectionObject::getProperties()
140     * reset(), current(), etc. Use Iterator methods instead.
141     * Potentially others working on object properties as a list.
142     * Other internal functions that iterate over an array, but which
143       previously silently accepted an ArrayObject as well; eg curl_setopt()
144       when used with an option that expects an array.
145
146    (array) casts are *not* affected. They will continue to return either the
147    wrapped array, or the ArrayObject properties, depending on whether the
148    STD_PROP_LIST flag is used.
149  . SplPriorityQueue::setExtractFlags() will throw an exception if zero is
150    passed. Previously this would generate a recoverable fatal error on the
151    next extraction operation.
152  . ArrayObject, ArrayIterator, SplDoublyLinkedList and SplObjectStorage now
153    support the __serialize() + __unserialize() mechanism in addition to the
154    Serializable interface. This means that serialization payloads created on
155    older PHP versions can still be unserialized, but new payloads created by
156    PHP 7.4 will not be understood by older versions.
157
158- Standard:
159  . The "o" serialization format has been removed. As it is never produced by
160    PHP, this may only break unserialization of manually crafted strings.
161  . Password hashing algorithm identifiers are now nullable strings rather
162    than integers.
163
164     * PASSWORD_DEFAULT was int 1; now is null in PHP <7.4.3 and string '2y' afterwards
165     * PASSWORD_BCRYPT was int 1; now is string '2y'
166     * PASSWORD_ARGON2I was int 2; now is string 'argon2i'
167     * PASSWORD_ARGON2ID was int 3; now is string 'argon2id'
168
169    Applications correctly using the constants PASSWORD_DEFAULT,
170    PASSWORD_BCRYPT, PASSWORD_ARGON2I, and PASSWORD_ARGON2ID will continue to
171    function correctly.
172  . htmlentities() will now throw a notice (instead of a strict standards
173    warning) if it is used with an encoding for which only basic entity
174    substitution is supported, in which case it is equivalent to
175    htmlspecialchars().
176  . fread() and fwrite() will now return false if the operation failed.
177    Previously an empty string or 0 was returned. EAGAIN/EWOULDBLOCK are not
178    considered failures.
179  . fread() and fwrite() on plain files will now throw a notice on failure,
180    such as when trying to write to a read-only file resource.
181  . The stream_read() and stream_write() methods on stream wrappers now
182    interpret "false" as a failure return values. If no data is available, but
183    no error occurred, an empty string should be returned instead.
184  . round(-0.0) will now return -0.0 rather than +0.0.
185
186- Tokenizer:
187  . token_get_all() will now emit a T_BAD_CHARACTER token for unexpected
188    characters instead of leaving behind holes in the token stream.
189
190========================================
1912. New Features
192========================================
193
194- Core:
195  . Added support for typed properties. For example:
196
197        class User {
198            public int $id;
199            public string $name;
200        }
201
202    This will enforce that $user->id can only be assigned integers and
203    $user->name can only be assigned strings. For more information see the
204    RFC: https://wiki.php.net/rfc/typed_properties_v2
205
206  . Added support for arrow functions with implicit by-value scope binding.
207    For example:
208
209        $factor = 10;
210        $nums = array_map(fn($num) => $num * $factor, $nums);
211
212    RFC: https://wiki.php.net/rfc/arrow_functions_v2
213
214  . Added support for limited return type covariance and argument type
215    contravariance. The following code will now work:
216
217        class A {}
218        class B extends A {}
219
220        class Producer {
221            public function method(): A {}
222        }
223        class ChildProducer extends Producer {
224            public function method(): B {}
225        }
226
227    Full variance support is only available if autoloading is used. Inside a
228    single file only non-cyclic type references are possible, because all
229    classes need to be available before they are referenced.
230    RFC: https://wiki.php.net/rfc/covariant-returns-and-contravariant-parameters
231
232  . Added support for coalesce assign (??=) operator. For example:
233
234        $array['key'] ??= computeDefault();
235        // is roughly equivalent to
236        if (!isset($array['key'])) {
237            $array['key'] = computeDefault();
238        }
239
240    RFC: https://wiki.php.net/rfc/null_coalesce_equal_operator
241
242  . Added support for unpacking inside arrays. For example:
243
244        $arr1 = [3, 4];
245        $arr2 = [1, 2, ...$arr1, 5];
246        // $arr2 == [1, 2, 3, 4, 5]
247
248    RFC: https://wiki.php.net/rfc/spread_operator_for_array
249
250  . Added support for underscore separators in numeric literals. Some examples:
251
252        6.674_083e-11; // float
253        299_792_458;   // decimal
254        0xCAFE_F00D;   // hexadecimal
255        0b0101_1111;   // binary
256
257    RFC: https://wiki.php.net/rfc/numeric_literal_separator
258
259  . Support for WeakReferences has been added.
260    RFC: https://wiki.php.net/rfc/weakrefs
261
262  . Throwing exceptions from __toString() is now permitted. Previously this
263    resulted in a fatal error. Existing recoverable fatals in string conversions
264    have been converted to Error exceptions.
265    RFC: https://wiki.php.net/rfc/tostring_exceptions
266
267- CURL:
268  . CURLFile now supports stream wrappers in addition to plain file names, if
269    the extension has been built against libcurl >= 7.56.0.  The streams may
270    need to be seekable.
271
272- Filter:
273  . The FILTER_VALIDATE_FLOAT filter now supports the min_range and max_range
274    options, with the same semantics as FILTER_VALIDATE_INT.
275
276- FFI:
277  . A new extension which provides a simple way to call native functions, access
278    native variables and create/access data structures defined in C libraries.
279    RFC: https://wiki.php.net/rfc/ffi
280
281- GD:
282  . Added the "scatter" image filter (IMG_FILTER_SCATTER) to apply a scatter
283    filter to images. This filter has the following prototype:
284
285        imagefilter($im, IMG_FILTER_SCATTER, int $sub, int $plus, array $colors = []);
286
287    The $colors array can be populated with a set of indexed colors to
288    apply the scatter pixel shifting on.
289
290    Note, the result of this filter is always random.
291
292- Hash:
293  . Added "crc32c" hash using Castagnoli's polynomial. This crc32 variant is
294    used by storage systems, such as iSCSI, SCTP, Btrfs and ext4.
295
296- Mbstring:
297  . Added mb_str_split() function, which provides the same functionality as
298    str_split(), but operating on code points rather than bytes.
299    RFC: https://wiki.php.net/rfc/mb_str_split
300  . Added mbstring.regex_retry_limit ini setting defaulting to 1000000. It
301    limits the amount of backtracking that may be performed during one mbregex
302    match and thus protects against exponential backtracking attacks (ReDOS).
303    This setting only takes effect when linking against oniguruma >= 6.8.0.
304
305- OPcache:
306  . Support for preloading code has been added.
307    RFC: https://wiki.php.net/rfc/preload
308
309- PCRE:
310  . The preg_replace_callback() and preg_replace_callback_array() functions now
311    accept an additional $flags argument, with support for the
312    PREG_OFFSET_CAPTURE and PREG_UNMATCHED_AS_NULL flags. This influences the
313    format of the matches array passed to the callback function.
314
315- PDO:
316  . The username and password can now be specified as part of the PDO DSN for
317    the mysql, mssql, sybase, dblib, firebird and oci drivers. Previously this
318    was only supported by the pgsql driver. If a username/password is specified
319    both in the constructor and the DSN, the constructor takes precedence.
320
321        new PDO("mysql:host=xxx;port=xxx;dbname=xxx;user=xxx;password=xxx");
322
323- PDO_OCI:
324  . PDOStatement::getColumnMeta() is now available
325
326- PDO_SQLite:
327  . PDOStatement::getAttribute(PDO::SQLITE_ATTR_READONLY_STATEMENT) allows
328    checking whether the statement is read-only, i.e. if it doesn't modify
329    the database.
330  . PDO::setAttribute(PDO::SQLITE_ATTR_EXTENDED_RESULT_CODES, true) enables the
331    use of SQLite3 extended result codes in errorInfo().
332
333- SQLite3:
334  . Added SQLite3::lastExtendedErrorCode() to fetch the last extended result
335    code.
336  . Added SQLite3::enableExtendedResultCodes($enable = true), which will make
337    SQLite3::lastErrorCode() return extended result codes.
338
339- Standard:
340  . strip_tags() now also accepts an array of allowed tags: Instead of
341    strip_tags($str, '<a><p>') you can now write strip_tags($str, ['a', 'p']).
342
343  . A new mechanism for custom object serialization has been added, which
344    uses two new magic methods:
345
346        // Returns array containing all the necessary state of the object.
347        public function __serialize(): array;
348
349        // Restores the object state from the given data array.
350        public function __unserialize(array $data): void;
351
352    The new serialization mechanism supersedes the Serializable interface,
353    which will be deprecated in the future.
354
355    RFC: https://wiki.php.net/rfc/custom_object_serialization
356
357  . A new 'max_depth' option for unserialize(), as well as an
358    unserialize_max_depth ini setting have been added. These control the
359    maximum depth of structures permitted during unserialization, and are
360    intended to prevent stack overflows. The default depth limit is 4096 and
361    can be disabled by setting unserialize_max_depth=0.
362
363  . array_merge() and array_merge_recursive() may now be called without any
364    arguments, in which case they will return an empty array. This is useful
365    in conjunction with the spread operator, e.g. array_merge(...$arrays).
366
367  . proc_open() now accepts an array instead of a string for the command. In
368    this case the process will be opened directly (without going through a
369    shell) and PHP will take care of any necessary argument escaping.
370
371        proc_open(['php', '-r', 'echo "Hello World\n";'], $descriptors, $pipes);
372
373  . proc_open() now supports "redirect" and "null" descriptors. For example:
374
375        // Like 2>&1 on the shell
376        proc_open($cmd, [1 => ['pipe', 'w'], 2 => ['redirect', 1]], $pipes);
377        // Like 2>/dev/null or 2>nul on the shell
378        proc_open($cmd, [1 => ['pipe', 'w'], 2 => ['null']], $pipes);
379
380  . password_hash() has argon2i(d) implementations from ext/sodium when PHP is
381    built without libargon.
382
383    RFC: https://wiki.php.net/rfc/sodium.argon.hash
384
385========================================
3863. Changes in SAPI modules
387========================================
388
389========================================
3904. Deprecated Functionality
391========================================
392
393- Core:
394  . Nesting ternary operators without explicit parentheses is deprecated:
395
396        // Code like
397        $a ? $b : $c ? $d : $e
398        // should be replaced by (current interpretation)
399        ($a ? $b : $c) ? $d : $e
400        // or (likely intended interpretation)
401        $a ? $b : ($c ? $d : $e)
402
403    RFC: https://wiki.php.net/rfc/ternary_associativity
404  . The array and string offset access syntax using curly braces is deprecated.
405    Use $str[$idx] instead of $str{$idx}.
406    RFC: https://wiki.php.net/rfc/deprecate_curly_braces_array_access
407  . The (real) cast is deprecated, use (float) instead.
408  . Unbinding $this of a non-static method through a combination of
409    ReflectionMethod::getClosure() and closure rebinding is deprecated. Doing
410    so is equivalent to calling a non-static method statically, which has been
411    deprecated since PHP 7.0.
412  . Unbinding $this of a non-static closure that uses $this is deprecated.
413  . Using "parent" inside a class without a parent is deprecated, and will throw
414    a compile-time error in the future. Currently an error will only be
415    generated if/when the parent is accessed at run-time.
416  . The allow_url_include ini directive is deprecated. Enabling it will generate
417    a deprecation notice at startup.
418
419- COM:
420  . Importing type libraries with case-insensitive constant registering has been
421    deprecated.
422
423- Filter:
424  . FILTER_SANITIZE_MAGIC_QUOTES is deprecated, use FILTER_SANITIZE_ADD_SLASHES
425    instead.
426
427- Mbstring:
428  . Passing a non-string pattern to mb_ereg_replace() is deprecated. Currently
429    non-string patterns are interpreted as ASCII codepoints. In PHP 8 the
430    pattern will be interpreted as a string instead.
431  . Passing the encoding as 3rd parameter to mb_strrpos() is deprecated. Instead
432    pass a 0 offset and encoding as 4th parameter.
433
434- LDAP:
435  . ldap_control_paged_result_response and ldap_control_paged_result are
436    deprecated. Pagination controls can be sent along with ldap_search instead.
437
438- Reflection:
439  . Calls to ReflectionType::__toString() now generate a deprecation notice.
440    This method has been deprecated in favor of ReflectionNamedType::getName()
441    in the documentation since PHP 7.1, but did not throw a deprecation notice
442    for technical reasons.
443  . The export() methods on all Reflection classes are deprecated. Construct a
444    Reflection object and convert it to string instead:
445
446        // ReflectionClass::export(Foo::class, false) is:
447        echo new ReflectionClass(Foo::class), "\n";
448        // $str = ReflectionClass::export(Foo::class, true) is:
449        $str = (string) new ReflectionClass(Foo::class);
450
451- Socket:
452  . The AI_IDN_ALLOW_UNASSIGNED and AI_IDN_USE_STD3_ASCII_RULES flags for
453    socket_addrinfo_lookup() are deprecated, due to an upstream deprecation in
454    glibc.
455
456- Standard:
457  . Passing invalid characters to ''base_convert()'', ''bindec()'', ''octdec()''
458    and ''hexdec()'' will now generate a deprecation notice. The result will
459    still be computed as if the invalid characters did not exist. Leading and
460    trailing whitespace, as well as prefixes of type 0x (depending on base)
461    continue to be allowed.
462  . Using array_key_exists() on objects is deprecated. Instead either isset()
463    or property_exists() should be used.
464  . The is_real() function is deprecated, use is_float() instead.
465  . The get_magic_quotes_gpc() and get_magic_quotes_runtime() functions are
466    deprecated. They always return false.
467  . The hebrevc() function is deprecated. It can be replaced with
468    nl2br(hebrev($str)), or preferably the use of Unicode RTL support.
469  . The convert_cyr_string() function is deprecated. It can be replaced by one
470    of mb_convert_string(), iconv() or UConverter.
471  . The money_format() function is deprecated. It can be replaced by the
472    intl NumberFormatter functionality.
473  . The ezmlm_hash() function is deprecated.
474  . The restore_include_path() function is deprecated. It can be replaced by
475    ini_restore('include_path').
476  . Passing parameters to implode() in reverse order is deprecated, use
477    implode($glue, $parts) instead of implode($parts, $glue).
478
479========================================
4805. Changed Functions
481========================================
482
483- SPL:
484  . SplFileObject::fputcsv(), ::fgetcsv() and ::setCsvControl() now accept an
485    empty string as $escape argument, which disables the proprietary PHP
486    escaping mechanism. SplFileObject::getCsvControl() now may also return an
487    empty string for the third array element, accordingly.
488
489- Standard:
490  . fputcsv() and fgetcsv() now accept an empty string as $escape argument,
491    which disables the proprietary PHP escaping mechanism. The behavior of
492    str_getcsv() has been adjusted accordingly (formerly, an empty string was
493    identical to using the default).
494  . proc_open() on Windows can be passed a "create_process_group" option. It
495    is required, if the child process is supposed to handle CTRL events.
496  . password_hash() now accepts nullable string and int as $algo argument.
497  . password_needs_rehash() now accepts nullable string and int as $algo
498    argument.
499
500========================================
5016. New Functions
502========================================
503
504- Core:
505  . Added get_mangled_object_vars($object) function, which returns the mangled
506    object properties. It returns the same result as (array) $object, with the
507    exception that it ignores overloaded array casts, such as used by
508    ArrayObject.
509
510- GD:
511  . Added imagecreatefromtga() function, which allows reading images in TGA
512    format. TGA support is now also indicated by gd_info() and imagetypes().
513    Note that TGA images are not recognized by imagecreatefromstring() and
514    getimagesize().
515
516- OpenSSL:
517  . Added openssl_x509_verify(mixed cert, mixed key) function that verifies the
518    signature of the certificate using a public key. A wrapper around the
519    OpenSSL's X509_verify() function.
520    See <https://github.com/php/php-src/pull/3624>.
521
522- Pcntl:
523  . Added bool pcntl_unshare(int flags) function which allows dissociating
524    parts of the process execution context which are currently being shared with
525    other processes. Explicitly, it allows you to unshare the mount, IPC, UTS,
526    network, PID, user and cgroup namespaces.
527
528- SQLite3:
529  . Added SQLite3Stmt::getSQL() to retrieve the SQL of the statement. If true is
530    passed as $expanded argument, query parameters will be replaced in the
531    return value by their currently bound value, if libsqlite ≥ 3.14 is used.
532  . Added SQLite3::backup() to create database backups via the SQLite3 online
533    backup API.
534
535- Standard
536  . bool sapi_windows_set_ctrl_handler(callable handler, [, bool add = true]) -
537    set or remove a handler function upon receiving a CTRL event. The handler
538    function is expected to have this signature: "function handler(int $event)".
539  . bool sapi_windows_generate_ctrl_event(int type, int pid) - send a CTRL event
540    to another process.
541  . array password_algos() - return a complete list of all registered password
542    hashing algorithms. For more details see the RFC:
543    https://wiki.php.net/rfc/password_registry
544
545========================================
5467. New Classes and Interfaces
547========================================
548
549- Reflection:
550  . A new ReflectionReference class has been added, which allows detecting
551    references and comparing them for identity. For more details see the RFC:
552    https://wiki.php.net/rfc/reference_reflection
553
554========================================
5558. Removed Extensions and SAPIs
556========================================
557
558- Interbase:
559  . The interbase extension has been moved to PECL. Access to an InterBase
560    and/or FireBird based database is still available with the PDO_Firebird
561    extension. For more details see the RFC:
562    https://wiki.php.net/rfc/deprecate-and-remove-ext-interbase
563
564- Recode:
565  . The recode extension has been moved to PECL. For character set/encoding
566    conversion the iconv or mbstring extensions could be used instead.
567    RFC: https://wiki.php.net/rfc/unbundle_recode
568
569- WDDX:
570  . The WDDX extension has been deprecated and moved to PECL.
571    RFC: https://wiki.php.net/rfc/deprecate-and-remove-ext-wddx
572
573========================================
5749. Other Changes to Extensions
575========================================
576
577 DBA:
578   . As of PHP 7.4.2, dba_open() accepts a fifth optional parameter for lmdb
579     databases which allows to specify the mapsize. The parameter defaults to
580     zero, in which case the compiled in default mapsize (usually 1048576) will
581     be used. The mapsize should be a multiple of the page size of the OS.
582
583- GD:
584  . The behavior of imagecropauto() in the bundled libgd has been synced with
585    that of system libgd:
586     * IMG_CROP_DEFAULT is no longer falling back to IMG_CROP_SIDES
587     * Threshold-cropping now uses the algorithm of system libgd
588  . The default $mode parameter of imagecropauto() has been changed to
589    IMG_CROP_DEFAULT; passing -1 is now deprecated.
590  . imagescale() now supports aspect ratio preserving scaling to a fixed height
591    by passing -1 as $new_width.
592
593- Filter:
594  . The filter extension no longer exposes --with-pcre-dir for Unix builds and
595    can now reliably be built as shared when using ./configure once more.
596
597- Hash:
598  . The hash extension cannot be disabled anymore and is always an integral part
599    of any PHP build, similar to the date extension.
600
601- Intl:
602  . The Intl extension now requires at least ICU 50.1.
603  . ResourceBundle now implements Countable.
604
605- Ldap:
606  . Support for nsldap has been removed.
607  . Support for umich_ldap has been removed.
608
609- Libxml:
610  . All libxml based extensions now require libxml 2.7.6 or newer.
611
612- Mbstring:
613  . The oniguruma library is no longer bundled with PHP, instead libonig needs
614    to be available on the system. Alternatively --disable-mbregex can be used
615    to disable the mbregex component.
616
617- OPcache:
618  . The --disable-opcache-file|--enable-opcache-file configure options have been
619    removed in favor of the opcache.file_cache INI directive.
620
621- PDO:
622  . It is now possible to escape question marks in SQL queries to avoid them
623    being interpreted as parameter placeholders. Writing "??" allows sending
624    a single question mark to the database and e.g. use the PostgreSQL JSON key
625    exists "?" operator. For more details see the RFC:
626    https://wiki.php.net/rfc/pdo_escape_placeholders
627
628- PDO_Firebird:
629  . The extension now also support dialect 1 in addition to dialect 3.
630
631- Reflection:
632  . Numeric value of class, property, function and constant modifiers was
633    changed. Don't filter methods and properties through
634    ReflectionClass::getMethods() and ReflectionClass::getProperties(), or test
635    results of Reflection...::getModifiers(), using hard-coded numeric values.
636    Use corresponding constants instead (e.g. ReflectionMethod::IS_PUBLIC).
637
638- SimpleXML:
639  . SimpleXMLElement now implements Countable.
640
641- SQLite3:
642  . The bundled libsqlite has been removed. To build the SQLite3 extension a
643    system libsqlite3 ≥ 3.7.4 is now required. To build the PDO_SQLite extension
644    a system libsqlite3 ≥ 3.5.0 is now required.
645  . (Un)serialization of SQLite3, SQLite3Stmt and SQLite3Result is now
646    explicitly forbidden. Formerly, serialization of instances of these classes
647    was possible, but unserialization yielded unusable objects.
648  . The @param notation can now also be used to denote SQL query parameters.
649
650- Zip:
651  . The bundled libzip library has been removed. A system libzip >= 0.11 is now
652    necessary to build the extension.
653
654========================================
65510. New Global Constants
656========================================
657
658- Mbstring:
659  . MB_ONIGURUMA_VERSION specifies the version of the oniguruma library against
660    which mbregex has been built.
661
662- Socket:
663  . Added FreeBSD-specific socket options:
664  . SO_LABEL
665  . SO_PEERLABEL
666  . SO_LISTENQLIMIT
667  . SO_LISTENQLEN
668  . SO_USER_COOKIE
669
670- Standard:
671  . PHP_WINDOWS_EVENT_CTRL_C
672  . PHP_WINDOWS_EVENT_CTRL_BREAK
673
674- Tidy:
675  . TIDY_TAG_ARTICLE
676  . TIDY_TAG_ASIDE
677  . TIDY_TAG_AUDIO
678  . TIDY_TAG_BDI
679  . TIDY_TAG_CANVAS
680  . TIDY_TAG_COMMAND
681  . TIDY_TAG_DATALIST
682  . TIDY_TAG_DETAILS
683  . TIDY_TAG_DIALOG
684  . TIDY_TAG_FIGCAPTION
685  . TIDY_TAG_FIGURE
686  . TIDY_TAG_FOOTER
687  . TIDY_TAG_HEADER
688  . TIDY_TAG_HGROUP
689  . TIDY_TAG_MAIN
690  . TIDY_TAG_MARK
691  . TIDY_TAG_MENUITEM
692  . TIDY_TAG_METER
693  . TIDY_TAG_NAV
694  . TIDY_TAG_OUTPUT
695  . TIDY_TAG_PROGRESS
696  . TIDY_TAG_SECTION
697  . TIDY_TAG_SOURCE
698  . TIDY_TAG_SUMMARY
699  . TIDY_TAG_TEMPLATE
700  . TIDY_TAG_TIME
701  . TIDY_TAG_TRACK
702  . TIDY_TAG_VIDEO
703
704========================================
70511. Changes to INI File Handling
706========================================
707
708- zend.exception_ignore_args
709  . New INI directive to include or exclude arguments from stack traces
710    generated for exceptions.
711
712- opcache.preload_user
713  . New INI directive to specify the user account under which preloading code
714    is executed, if it was to be run as root otherwise (which is not allowed
715    for security reasons).
716
717========================================
71812. Windows Support
719========================================
720
721- stat:
722  . The stat implementation has been refactored.
723    - An inode number is delivered and is based on the NTFS file index.
724    - The device number is now based on the volume serial number.
725
726  Note that both values are derived from the system and provided as is on 64-bit
727  systems. On 32-bit systems, these values might overflow the 32-bit integer in
728  PHP, so they're fake.
729
730- CTRL+C and CTRL+BREAK on console can be caught by setting a handler function
731  with sapi_windows_set_ctrl_handler().
732
733- configure now regards additional CFLAGS and LDFLAGS set as environment
734  variables.
735
736- OPcache now supports an arbitrary amount of separate caches per user via
737  the INI directive opcache.cache_id. All processes with the same cache ID and
738  user share an OPcache instance.
739
740- The OpenSSL default config path has been changed to
741  "C:\Program Files\Common Files\SSL\openssl.cnf" and
742  "C:\Program Files (x86)\Common Files\SSL\openssl.cnf", respectively.
743
744========================================
74513. Migration to pkg-config
746========================================
747
748A number of extensions have been migrated to exclusively use pkg-config for the
749detection of library dependencies. Generally, this means that instead of using
750--with-foo-dir=DIR or similar only --with-foo is used. Custom library paths can
751be specified either by adding additional directories to PKG_CONFIG_PATH or by
752explicitly specifying compilation options through FOO_CFLAGS and FOO_LIBS.
753
754The following extensions and SAPIs are affected:
755
756- Curl:
757  . --with-curl no longer accepts a directory.
758
759- Enchant:
760  . --with-enchant no longer accepts a directory.
761
762- FPM:
763  . --with-fpm-systemd now uses only pkg-config for libsystem checks. The
764    libsystemd minimum required version is 209.
765
766- GD:
767  . --with-gd becomes --enable-gd (whether to enable the extension at all) and
768    --with-external-gd (to opt into using an external libgd, rather than the
769    bundled one).
770  . --with-png-dir has been removed. libpng is required.
771  . --with-zlib-dir has been removed. zlib is required.
772  . --with-freetype-dir becomes --with-freetype.
773  . --with-jpeg-dir becomes --with-jpeg.
774  . --with-webp-dir becomes --with-webp.
775  . --with-xpm-dir becomes --with-xpm.
776
777- IMAP:
778  . --with-kerberos no longer accepts a directory.
779
780- Intl:
781  . --with-icu-dir has been removed. If --enable-intl is passed, then libicu is
782    always required.
783
784- Ldap:
785  . --with-ldap-sasl no longer accepts a directory.
786
787- Libxml:
788  . --with-libxml-dir has been removed.
789  . --enable-libxml becomes --with-libxml.
790  . --with-libexpat-dir has been renamed to --with-expat and no longer accepts a
791    directory.
792
793- LiteSpeed:
794  . --with-litespeed becomes --enable-litespeed.
795
796- Mbstring:
797  . --with-onig has been removed. Unless --disable-mbregex has been passed,
798    libonig is required.
799
800- ODBC:
801  . --with-iodbc no longer accepts a directory.
802  . --with-unixODBC without a directory now uses pkg-config (preferred).
803    Directory is still accepted for old versions without libodbc.pc.
804
805- OpenSSL:
806  . --with-openssl no longer accepts a directory.
807  . --with-kerberos no longer accepts a directory.
808
809- PCRE:
810  . --with-pcre-regex has been removed. Instead --with-external-pcre is provided
811    to opt into using an external PCRE library, rather than the bundled one.
812
813- PDO_SQLite:
814  . --with-pdo-sqlite no longer accepts a directory.
815
816- Readline:
817  . --with-libedit no longer accepts a directory.
818
819- Sodium:
820  . --with-sodium no longer accepts a directory.
821
822- SQLite3:
823  . --with-sqlite3 no longer accepts a directory.
824
825- XSL:
826  . --with-xsl no longer accepts a directory.
827
828- Zip:
829  . --with-libzip has been removed.
830  . --enable-zip becomes --with-zip.
831
832========================================
83314. Other Changes
834========================================
835
836========================================
83715. Performance Improvements
838========================================
839
840- Core:
841  . A specialized VM opcode for the array_key_exists() function has been added,
842    which improves performance of this function if it can be statically
843    resolved. In namespaced code, this may require writing \array_key_exists()
844    or explicitly importing the function.
845
846- PCRE:
847  . When preg_match() in UTF-8 mode ("u" modifier) is repeatedly called on the
848    same string (but possibly different offsets), it will only be checked for
849    UTF-8 validity once.
850