Backward Incompatible Changes
PHP Core
Array-style access of non-arrays
Trying to use values of type null, bool,
int, float or resource as an
array (such as $null["key"]
) will now generate a notice.
get_declared_classes() function
The get_declared_classes() function no longer returns anonymous classes that have not been instantiated yet.
fn
keyword
fn
is now a reserved keyword. In particular,
it can no longer be used as a function or class name.
It can still be used as a method or class constant name.
<?php
tag at end of file
<?php
at the end of the file (without trailing newline)
will now be interpreted as an opening PHP tag. Previously it was interpreted
either as a short opening tag followed by literal php
and
resulted in a syntax error (with short_open_tag=1
)
or was interpreted as a literal <?php
string
(with short_open_tag=0
).
Stream wrappers
When using include/require on a stream,
streamWrapper::stream_set_option()
will be invoked with the STREAM_OPTION_READ_BUFFER
option.
Custom stream wrapper implementations may need to implement the
streamWrapper::stream_set_option() method to
avoid a warning (always returning false
is a sufficient implementation).
Serialization
The o
serialization format has been removed.
As it is never produced by PHP, this may only break unserialization of
manually crafted strings.
Password algorithm constants
Password hashing algorithm identifiers are now nullable strings rather than integers.
-
PASSWORD_DEFAULT
was int 1; now is string '2y' (in PHP 7.4.0, 7.4.1, and 7.4.2 it wasnull
) -
PASSWORD_BCRYPT
was int 1; now is string '2y' -
PASSWORD_ARGON2I
was int 2; now is string 'argon2i' -
PASSWORD_ARGON2ID
was int 3; now is string 'argon2id'
Applications correctly using the constants PASSWORD_DEFAULT, PASSWORD_BCRYPT, PASSWORD_ARGON2I, and PASSWORD_ARGON2ID will continue to function correctly.
htmlentities() function
htmlentities() will now raise a notice (instead of a strict standards warning) if it is used with an encoding for which only basic entity substitution is supported, in which case it is equivalent to htmlspecialchars().
fread() and fwrite() function
fread() and fwrite() will now
return false
if the operation failed.
Previously an empty string or 0 was returned.
EAGAIN/EWOULDBLOCK are not considered failures.
These functions now also raise a notice on failure, such as when trying to write to a read-only file resource.
BCMath Arbitrary Precision Mathematics
BCMath functions will now warn if a non well-formed number is passed, such
as "32foo"
. The argument will be interpreted as zero, as before.
CURL
Attempting to serialize a CURLFile class will now generate an exception. Previously the exception was only thrown on unserialization.
Using CURLPIPE_HTTP1
is deprecated, and is no longer
supported as of cURL 7.62.0.
The $version
parameter of curl_version()
is deprecated. If any value not equal to the default CURLVERSION_NOW
is passed, a warning is raised and the parameter is ignored.
Date and Time
Calling var_dump() or similar on a DateTime or DateTimeImmutable instance will no longer leave behind accessible properties on the object.
Comparison of DateInterval objects
(using ==
, <
, and so on) will now generate
a warning and always return false
. Previously all DateInterval
objects were considered equal, unless they had properties.
Intl
The default parameter value of idn_to_ascii() and
idn_to_utf8() is now INTL_IDNA_VARIANT_UTS46
instead of the deprecated INTL_IDNA_VARIANT_2003
.
MySQLi
The embedded server functionality has been removed. It was broken since at least PHP 7.0.
The undocumented mysqli::$stat
property has been removed
in favor of mysqli::stat().
OpenSSL
The openssl_random_pseudo_bytes() function will now
throw an exception in error situations, similar to random_bytes().
In particular, an Error is thrown if the number of
requested bytes is less than or equal to zero, and an Exception
is thrown if sufficient randomness cannot be gathered.
The $crypto_strong output
argument is guaranteed to always
be true
if the function does not throw, so explicitly checking it is not necessary.
Regular Expressions (Perl-Compatible)
When PREG_UNMATCHED_AS_NULL
mode is used, trailing
unmatched capturing groups will now also be set to null
(or
[null, -1]
if offset capture is enabled).
This means that the size of the $matches
will always be the same.
PHP Data Objects
Attempting to serialize a PDO or PDOStatement instance will now generate an Exception rather than a PDOException, consistent with other internal classes which do not support serialization.
Reflection
Reflection objects will now generate an exception if an attempt is made to serialize them. Serialization for reflection objects was never supported and resulted in corrupted reflection objects. It has been explicitly prohibited now.
The values of the class constant of ReflectionClassConstant, ReflectionMethod and ReflectionProperty have changed.
Standard PHP Library (SPL)
Calling get_object_vars() on an ArrayObject
instance will now always return the properties of the ArrayObject
itself (or a subclass). Previously it returned the values of the wrapped
array/object unless the ArrayObject::STD_PROP_LIST
flag was specified.
Other affected operations are:
- ReflectionObject::getProperties()
- reset(), current(), etc. Use Iterator methods instead.
- Potentially others working on object properties as a list, e.g. array_walk().
(array)
casts are not affected. They will continue to
return either the wrapped array, or the ArrayObject
properties, depending on whether the ArrayObject::STD_PROP_LIST
flag is used.
SplPriorityQueue::setExtractFlags() will throw an exception if zero is passed. Previously this would generate a recoverable fatal error on the next extraction operation.
ArrayObject, ArrayIterator,
SplDoublyLinkedList and SplObjectStorage
now support the __serialize()
and __unserialize()
mechanism in addition to the Serializable interface.
This means that serialization payloads created on older PHP versions can still be
unserialized, but new payloads created by PHP 7.4 will not be understood by older versions.
Tokenizer
token_get_all() will now emit a
T_BAD_CHARACTER
token for unexpected
characters instead of leaving behind holes in the token stream.
Incoming Cookies
As of PHP 7.4.11, the names of incoming cookies are no longer url-decoded for security reasons.