Backward Incompatible Changes
Although not explicitly stated in this section,
every new function,
class, interface, enum,
or constant
may cause a redeclaration Error to be thrown.
PHP Core
exit behavioral change
The exit (and die) language
constructs now behave more like a function.
This means that they can now be passed like callables,
are affected by the strict_types
declare statement,
and now perform the usual type coercions instead of casting any non-integer
value to a string.
As such, passing invalid types to exit and
die now consistently result in a
TypeError being thrown.
Recursion during comparison
Encountering recursion during comparison now results in an
Error exception instead of a
E_ERROR
fatal error.
Indirect Modification of readonly Properties
Indirect modification of readonly properties within __clone()
is no longer allowed, e.g. $ref = &$this->readonly
.
This was already forbidden for readonly initialization, and was an
oversight in the "readonly reinitialization during cloning" implementation.
Type Change of Constants
The PHP_DEBUG
and PHP_ZTS
constants are now of type bool.
Previously they were of type int.
Temporary Filename Length
The name of uploaded files and files created by the
tempnam function are now 13 bytes longer.
The total length is still platform-dependent.
Removal of E_STRICT
error level
The E_STRICT
error level has been removed,
as it was no longer in use within the PHP engine.
The E_STRICT
constant has been deprecated.
Extension Class Constants which are now Typed
The following extension class constants now declare a type on their
constants:
Resource to Object Migration
Several resources have been migrated to objects.
Return value checks using is_resource should be
replaced with checks for false
, unless specified otherwise.
DBA
The DBA functions now accept and return
Dba\Connection objects instead of
dba_connection
resources.
ODBC
The ODBC functions now accept and return
Odbc\Result objects instead of
odbc_result
resources.
The ODBC functions now accept and return
Odbc\Connection objects instead of
odbc_connection
resources.
SOAP
The SoapClient::$httpurl property is now a
Soap\Url object rather than a
soap_url
resource.
Checks using is_resource (i.e.
is_resource($client->httpurl)
) should be replaced with checks
for null
(i.e. $client->httpurl !== null
).
The SoapClient::$sdl property is now a
Soap\Sdl object rather than a
soap_sdl
resource.
Checks using is_resource (i.e.
is_resource($client->sdl)
) should be replaced with checks
for null
(i.e. $client->sdl !== null
).
New warnings and exceptions
New warnings and exceptions have been added which are triggered on
programming errors, i.e. invalid values provided as arguments.
Curl
curl_multi_select now throws a
ValueError if the
timeout
parameter is less than
0
or greater than PHP_INT_MAX
.
Gd
- imagejpeg
- imagewebp
- imagepng
- imageavif
now throw a
ValueError when an invalid
quality
is passed.
imageavif will now throw a
ValueError if an invalid
speed
parameter value is passed.
imagescale will now throw a
ValueError if the
width
or height
parameters underflows/overflows.
imagescale will now throw a
ValueError if an invalid
mode
parameter value is passed.
imagefilter will now throw a
ValueError with the
IMG_FILTER_SCATTER
filter
if the sub
or plus
parameters underflows/overflows.
Gettext
- bind_textdomain_codeset
- textdomain
- d*gettext
now throw a
ValueError if
domain
is the empty string.
Intl
resourcebundle_get,
ResourceBundle::get, and accessing offsets on
a ResourceBundle object now throw:
-
TypeError for invalid offset types
-
ValueError for an empty string
-
ValueError if the integer index does
not fit in a signed 32 bit integer
IntlDateFormatter::__construct throws a
ValueError if the
locale
is invalid.
NumberFormatter::__construct throws a
ValueError if the
locale
is invalid.
MBString
mb_encode_numericentity and
mb_decode_numericentity now check that the
map
is only composed of ints,
if not a ValueError is now thrown.
mb_http_input now always throw a
ValueError if type
is invalid.
mb_http_output now check that the
encoding
does not contain any null bytes,
if it does a ValueError is now thrown.
ODBC
odbc_fetch_row returns false
when
row
is less than or equal to 0
.
A warning is now emitted in this case.
PCNTL
The pcntl_sigprocmask,
pcntl_sigwaitinfo, and
pcntl_sigtimedwait functions now throw:
-
A ValueError if the
signals
array is empty
(except for pcntl_sigprocmask if the
mode
SIG_SETMASK
)
-
A TypeError if a value of the
signals
array is not an int
-
A ValueError if a value of the
signals
array is not a valid signal number
The pcntl_sigprocmask function now throws a
ValueError if the
mode
is not one of SIG_BLOCK
,
SIG_UNBLOCK
, or SIG_SETMASK
.
The pcntl_sigtimedwait function now throw:
-
A ValueError if
seconds
is less than 0
-
A ValueError if
nanoseconds
is less than 0
or greater than 1e9
-
A ValueError if both
seconds
and nanoseconds
are 0
SimpleXML
Calling simplexml_import_dom with a non-XML object
now throws a TypeError instead of a
ValueError.
Standard
The round function now validates the value of the
mode
and throw a
ValueError for invalid modes.
Previously, invalid modes would have been interpreted as
PHP_ROUND_HALF_UP
.
The str_getcsv now throws
ValueErrors when the
separator
and enclosure
arguments are not one byte long, or if the escape
argument is not one byte long nor the empty string.
This aligns the behaviour to be identical to the one of
fputcsv and fgetcsv.
The php_uname function now throws a
ValueError if the
mode
is invalid.
The "allowed_classes"
option for
unserialize now throws
TypeErrors and
ValueErrors if it is not an
array of class names.
XMLReader
Passing an invalid character encoding to
XMLReader::open or
XMLReader::XML now throws a
ValueError.
Passing a string containing null bytes previously emitted a
warning and now throws a ValueError.
XMLWriter
Passing a string containing null bytes previously emitted a
warning and now throws a ValueError.
XSL
XSLTProcessor::setParameter will now throw a
ValueError when its arguments contain null
bytes. This never actually worked correctly in the first place,
which is why it throws an exception now.
Calling XSLTProcessor::importStyleSheet with a
non-XML object now throws a TypeError
instead of a ValueError.
Failure to call a PHP function callback during evaluation now throws
instead of emitting a warning.
DOM
Some DOM methods previously returned false
or a
DOMException with code
DOM_PHP_ERR
if a new node could not be allocated.
They now consistently throw a DOMException
with code DOM_INVALID_STATE_ERR
.
This situation is extremely unlikely and the probability of being affected
is low.
As a result DOMImplementation::createDocument
now has a tentative return type of DOMDocument
instead of DOMDocument|false
.
Previously, DOMXPath objects could be cloned,
but resulted in an unusable object.
This is no longer possible, and cloning a DOMXPath
object now throws an Error.
The DOMImplementation::getFeature method has been removed.
GMP
The GMP class is now final and cannot be extended
anymore.
MBString
On invalid strings (those with encoding errors),
mb_substr now interprets character indices in the same
manner as most other mbstring functions.
This means that character indices returned by mb_strpos
can be passed to mb_substr.
For SJIS-Mac (MacJapanese) strings, character indices passed to
mb_substr now refer to the indices of the Unicode
codepoints which are produced when the string is converted to Unicode.
This is significant because around 40 SJIS-Mac characters convert to a
sequence of multiple Unicode codepoints.
MySQLi
The unused and undocumented constant
MYSQLI_SET_CHARSET_DIR
has been removed.
The MYSQLI_STMT_ATTR_PREFETCH_ROWS
constant has been
removed. The feature is unavailable with mysqlnd.
The MYSQLI_CURSOR_TYPE_FOR_UPDATE
and
MYSQLI_CURSOR_TYPE_SCROLLABLE
constants have been
removed. This functionality was never implemented,
neither with mysqlnd nor with libmysql.
The unused MYSQLI_TYPE_INTERVAL
constant, which is
currently a stub and an alias for MYSQLI_TYPE_ENUM
,
has been removed.
MySQLnd
The error code reported for MySQL server wait timeouts has been changed from
2006
to 4031
for MySQL server
versions 8.0.24 and above.
PCNTL
The pcntl_sigprocmask,
pcntl_sigwaitinfo, and
pcntl_sigtimedwait functions now always
return false
on failure.
In some case previously it could return the value -1
.
PCRE
The bundled pcre2lib has been updated to version 10.44.
As a consequence, this means {,3}
is now recognized
as a quantifier instead of as text.
Furthermore, the meaning of some character classes in UCP mode has changed.
Consult the » PCRE2 Changelog
for a full changelog.
PDO_DBLIB
The Pdo\Dblib::ATTR_STRINGIFY_UNIQUEIDENTIFIER
and
Pdo\Dblib::ATTR_DATETIME_CONVERT
attributes now act as
boolean attributes instead of integer attributes.
Thus setting the attribute via PDO::setAttribute
and retrieving it via PDO::getAttribute expects
and or return a bool.
PDO_FIREBIRD
The PDO::ATTR_AUTOCOMMIT
attribute now act as
boolean attributes instead of integer attributes.
Thus setting the attribute via PDO::setAttribute
and retrieving it via PDO::getAttribute expects
and or return a bool.
The extension now exposes some Firebird C++ APIs,
therefore building this extension now requires a C++ compiler.
Moreover, the extension must now be compiled against fbclient 3.0 or higher.
PDO_MYSQL
The PDO::ATTR_AUTOCOMMIT
,
PDO::ATTR_EMULATE_PREPARES
, and
PDO::MYSQL_ATTR_DIRECT_QUERY
attributes now act as
boolean attributes instead of integer attributes.
Thus setting the attribute via PDO::setAttribute
and retrieving it via PDO::getAttribute expects
and or return a bool.
PDO_PGSQL
The DSN's credentials, when set, are given priority over their PDO
constructor counterparts, being closer to the documentation states.
SimpleXML
SimpleXMLElement is not only a representation of an
XML element, but it is also a RecursiveIterator.
Prior to PHP 8.4.0, some of its methods (e.g.
SimpleXMLElement::asXML or
SimpleXMLElement::getName) and casting such
instances to string would implicitly reset the iterator.
This could cause unexpected infinite loops as the iterator was rewound.
For example:
SOAP
SoapClient::$typemap is now an array
rather than a resource.
Checks using is_resource (i.e.
is_resource($client->typemap)
) should be
replaced with checks for null
(i.e. $client->typemap !== null
).
The SOAP extension gained an optional dependency on the
session extension.
If PHP is built without the session extension and with the
--enable-rtld-now configure flag enabled,
startup errors will now occur if the SOAP
extension is also used.
To solve this either don't use rtld-now or load the session extension.
Standard
When using strcspn with
characters
being the empty string,
the length of the string is now returned instead of incorrectly stopping
at the first null byte.
http_build_query now correctly handles backed enums.
stream_bucket_make_writeable and
stream_bucket_new will now return a
StreamBucket instance instead of an instance of
stdClass.
Tidy
Failures in the constructor now throw exceptions rather than emitting
warnings and having a broken object.
XML
The xml_set_*_handler
functions now declare and check for an effective
signature of callablestringnull for the
handler
parameters.
Moreover, values of type string that correspond to method names,
of object set with xml_set_object are now checked to
see if the method exists on the class of the previously passed object.
This means that xml_set_object must now always be
called prior to setting method names as callables.
Passing an empty string to disable the handler is still allowed,
but deprecated.
However, as xml_set_object and passing
non-callable strings is deprecated.
It is recommended to change such instances with a callable
referring to the method directly.