Backward Incompatible Changes

Date

DateTime::createFromImmutable() now has a tentative return type of static, previously it was DateTime.

DateTimeImmutable::createFromMutable() now has a tentative return type of static, previously it was DateTimeImmutable.

ODBC

The ODBC extension now escapes the username and password for the case when both a connection string and username/password are passed, and the string must be appended to. Before, user values containing values needing escaping could have created a malformed connection string, or injected values from user-provided data. The escaping rules should be identical to the .NET BCL DbConnectionOptions behaviour.

PDO_ODBC

The PDO_ODBC extension also escapes the username and password when a connection string is passed. See the change to the ODBC extension for further details.

Standard

glob() now returns an empty array if all paths are restricted by open_basedir. Previously it returned false. Moreover, a warning is now emitted even if only some paths are restricted by open_basedir.

strtolower(), strtoupper(), stristr(), stripos(), strripos(), lcfirst(), ucfirst(), ucwords(), and str_ireplace() are no longer locale-sensitive. They now perform ASCII case conversion, as if the locale were "C". Localized versions of these functions are available in the MBString extension. Moreover, array_change_key_case(), and sorting with SORT_FLAG_CASE now also use ASCII case conversion.

str_split() returns an empty array for an empty string now. Previously it returned an array with a single empty string entry. mb_str_split() is not affected by this change as it was already behaving like that.

ksort() and krsort() now do numeric string comparison under SORT_REGULAR using the standard PHP 8 rules now.

Standard PHP Library (SPL)

The following methods now enforce their signature:

SplFileObject::hasChildren() now has a tentative return type of false, previously it was bool.

SplFileObject::getChildren() now has a tentative return type of null, previously it was ?RecursiveIterator.

GlobIterator now returns an empty array if all paths are restricted by open_basedir. Previously it returned false. Moreover, a warning is now emitted even if only some paths are restricted by open_basedir.