====== PHP RFC: Deprecations for PHP 8.6 ====== * Date: 2025-10-12 * Authors: * Gina Peter Banyard * Alexandre Daubois * Jordi Kroon * Status: Draft * Implementation: 8.6 * TBD ===== Introduction ===== The RFC proposes to deprecate the listed functionality in PHP 8.6 and remove it in PHP 9 (except where otherwise noted). The following list provides a short overview of the functionality targeted for deprecation, while more detailed explanation is provided in the Proposal section: * Passing objects for $array parameter of array_walk() and array_walk_recursive() * Passing objects for $options parameter of deflate_init() and inflate_init() * Passing objects to ArrayObject::exchangeArray() * Deprecate strcoll() * Deprecate SORT_LOCALE_STRING flag for sort() functions * Providing invalid values to log() second argument * Providing an invalid sorting order to scandir() * Providing invalid values to "work" and "blocks" options of the "bzip2.compress" filter * Deprecate mail.add_x_header INI setting * Deprecate mysqli::stmt_init() * Deprecate CURLOPT_PROGRESSFUNCTION for curl_setopt() * Deprecate is_double(), an alias of is_float() * Deprecate is_integer(), an alias of is_int() * Deprecate is_long(), an alias of is_int() * Deprecate doubleval(), an alias of floatval() * Deprecate returning a value from __construct() * Deprecate mysqli_get_charset() ===== Proposal ===== Each feature proposed for deprecation is voted separately and requires a 2/3 majority. All votes refer to deprecation in PHP 8.6 and removal in PHP 9 (except where otherwise noted). ==== Example Deprecation ==== * Author: Name Description ==== Passing objects for $array parameter of array_walk() and array_walk_recursive() ==== * Author: Gina Peter Banyard TODO: Reason to get rid of 'A' ZPP specifier Fallback: get_object_vars() The recursive version doesn't recursive if a value/property is an object. Due to taking by reference this breaks readonly properties, which is a similar issue that the ArrayObject with backing object deprecation is addressing ==== Passing objects for $options parameter of deflate_init() and inflate_init() ==== * Author: Gina Peter Banyard TODO: Reason to get rid of 'H' ZPP specifier Fallback: get_object_vars() ==== Passing objects to ArrayObject::exchangeArray() ==== * Author: Gina Peter Banyard TODO: Follow-up of 8.5 ArrayObject with objects deprecation https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_arrayobject_and_arrayiterator_with_objects ==== Deprecate strcoll() ==== * Author: Gina Peter Banyard TODO: * Not binary safe * Relies on global state from setlocale() * Alternative: Collator::compare() ==== Deprecate SORT_LOCALE_STRING flag for sort() functions ==== * Author: Gina Peter Banyard TODO: * Not binary safe, as internally it relies on the same behaviour as strcoll * Relies on global state from setlocale() * Alternative: Collator::sort(), Collator::asort(), Collator::sort(), Collator::sortWithSortKeys() ==== Providing invalid values to log() second argument ==== * Author: Alexandre Daubois Providing 1 or any number less or equal to 0 results on a NaN result. This is error-prone. Deprecating then throwing a ValueError in PHP 9.0 would help early error detection and avoid propagating a NaN value. ==== Providing an invalid sorting order to scandir() ==== * Author: Alexandre Daubois Providing an invalid value to the flags of scandir()'s sorting order is currently ignored and falls back to default values. Deprecating such behavior then throwing a ValueError in PHP 9.0 would help error detection and avoid undesired behavior when an invalid value is provided. ==== Providing invalid values to "work" and "blocks" options of the "bzip2.compress" filter ==== * Author: Alexandre Daubois Providing invalid values to the work and blocks options currently silently fails and falls back to default values when using the stream filter bzip2.compress. This may lead to unexpected behavior and difficult error detection. A too low value for work, a too high value for work, a too low value for blocks and a too high value for blocks should be deprecated and will throw a ValueError in PHP 9.0. ==== Deprecate mail.add_x_header INI setting ==== * Author: Gina Peter Banyard TODO: This is one of PHP's "expose yourself" INI settings that adds a ''X-PHP-Originating-Script'' header to every email send via the internal php_mail() function (called by mail, error_log(), and mb_mail()). It is off by default, and we don't see any reason why one would enable it. Moreover, it is trivially done by adding the header in the corresponding header parameter as followed: mail("To", "Subject", "Message", ['X-PHP-Originating-Script' => getmyuid() . ':' . basename(__SELF__)]); ==== Deprecate mysqli::stmt_init ==== * Author: Kamil Tekiela There is no justified reason for this function to exist. All it does is create a barren mysqli_stmt object that still needs to be prepared before use. It is the source of many ways in which mysqli objects can be left in an inconsistent state. It looks like it is only used in PHP unit tests, and in most cases for no good reason. Since this function doesn't provide any tangible value and leads to confusing code, it should be removed to reduce language complexity. $stmt = $mysqli->stmt_init(); $stmt->prepare($sql); // To: $stmt = $mysqli->prepare($sql); If accepted, calling mysqli::stmt_init() will emit a deprecation notice:
Deprecated: Function mysqli::stmt_init() is deprecated, use mysqli::prepare() instead
An alternative and almost unknown way of calling this function is through the constructor, which is equally useless. This proposal includes the deprecation of this feature, i.e. calling mysqli_stmt::__construct without the second argument. $stmt = new mysqli_stmt($mysqli); $stmt->prepare($sql); // To: $stmt = new mysqli_stmt($mysqli, $sql); If accepted, calling new mysqli_stmt() without the second argument will emit a deprecation notice:
Deprecated: Instantiation of mysqli_stmt without providing the $query parameter is deprecated
==== Deprecate is_double() ==== * Author: Jordi Kroon Following the [[rfc: deprecations_php_8_5#deprecate_non-standard_cast_names|deprecation of non standard cast names in PHP 8.5]], it is consistent to consider deprecating legacy aliases which preserve the same non canonical type terminology. is_double() is a legacy alias of is_float(). The name originates from historical internal naming and platform specific integer sizing, but it no longer communicates anything useful to userland code. Modern PHP presents the scalar type as float, and the canonical predicate is is_float(). Having is_double() as an additional alias offers no functional value and keeps outdated terminology alive. This proposal deprecates is_double() and recommends using is_float() instead. if (is_double($value)) { // ... } // To: if (is_float($value)) { // ... } If accepted, calling is_double() will emit a deprecation notice:
Deprecated: Function is_double() is deprecated, use is_float() instead
==== Deprecate is_integer() ==== * Author: Jordi Kroon Following the [[rfc: deprecations_php_8_5#deprecate_non-standard_cast_names|deprecation of non standard cast names in PHP 8.5]], it is consistent to consider deprecating legacy aliases which preserve the same non canonical type terminology. is_integer() is a legacy alias of is_int(). The name originates from historical internal naming and platform specific integer sizing, but it no longer communicates anything useful to userland code. Modern PHP presents the scalar type as int, and the canonical predicate is is_int(). Having is_integer() as an additional alias offers no functional value and keeps outdated terminology alive. This proposal deprecates is_integer() and recommends using is_int() instead. if (is_integer($value)) { // ... } // To: if (is_int($value)) { // ... } If accepted, calling is_integer() will emit a deprecation notice:
Deprecated: Function is_integer() is deprecated, use is_int() instead
==== Deprecate is_long() ==== * Author: Jordi Kroon Following the [[rfc: deprecations_php_8_5#deprecate_non-standard_cast_names|deprecation of non standard cast names in PHP 8.5]], it is consistent to consider deprecating legacy aliases which preserve the same non canonical type terminology. is_long() is a legacy alias of is_int(). The name originates from historical internal naming and platform specific integer sizing, but it no longer communicates anything useful to userland code. Modern PHP presents the scalar type as int, and the canonical predicate is is_int(). Having is_long() as an additional alias offers no functional value and keeps outdated terminology alive. This proposal deprecates is_long() and recommends using is_int() instead. if (is_long($value)) { // ... } // To: if (is_int($value)) { // ... } If accepted, calling is_long() will emit a deprecation notice:
Deprecated: Function is_long() is deprecated, use is_int() instead
==== Deprecate doubleval() ==== * Author: Jordi Kroon Following the [[rfc: deprecations_php_8_5#deprecate_non-standard_cast_names|deprecation of non standard cast names in PHP 8.5]], it is consistent to consider doubleval() as well, as it reflects the same legacy terminology as the deprecated (double) cast. doubleval() is a legacy alias of floatval(). Since floatval() is the canonical function name and matches the scalar type name float, keeping doubleval() provides no distinct behavior and only increases the number of ways to express the same conversion. This proposal deprecates doubleval() and recommends using floatval() instead. $number = doubleval($value); // To: $number = floatval($value); If accepted, calling doubleval() will emit a deprecation notice:
Deprecated: Function doubleval() is deprecated, use floatval() instead
==== Deprecate returning a value from __construct() ==== * Author: Tim Düsterhus TODO: See discussion in https://news-web.php.net/php.internals/129980 ==== Deprecate mysqli_get_charset() ==== * Author: Kamil Tekiela This function can be used to retrieve internal implementation details of the currently selected character set. It was able to provide more meaningful values when mysqli was compiled against libmysql but since PHP 8.2 it's no longer the case. The values reported are: * Character set name. The same as is returned by mysqli_character_set_name() * Default collation name for that charset as defined by mysqlnd, not by the server. As this information doesn't correspond to the true values defined by the server it is of no use to anyone. * Directory from which the charset information was imported. Used only with libmysql for dynamically loaded character sets. In mysqlnd it's an empty string. * Minimum and maximum character length of the character set. This is the only truly useful and correct information provided by this function, but it is still an implementation detail and in my opinion, not something that a PHP user would ever need to know. * Collation ID as defined by mysqlnd. It's just a number. It cannot be used for anything as it's not guaranteed that it's the same as defined in MySQL/MariaDB. As of PHP 8.6, it is set to 0 in all cases. Even in libmysql it's no longer used, other than for finding out the default collation of a charset for backwards compatibility reasons. * State. In libmysql it is always the value 1. In libmysql it was a bitflag of internal characteristics of the character set. It has no use in PHP. The proposal is to deprecate and remove this function, and its OO-style alias mysqli::get_charset(), and later remove it without a substitute. It's pretty unlikely that any PHP project still uses this function, and if they do, they probably don't know that it returns falsified information. The only uses I was able to find (see the user comment in PHP manual) are people incorrectly assuming that it returns the currently set collation. By removing this function, we reduce one more point of confusion for PHP users. If accepted, calling mysqli_get_charset() will emit a deprecation notice:
Deprecated: Function mysqli_get_charset() is deprecated, did you mean mysqli_character_set_name()?
The reason for this message is that mysqli_get_charset seems like a logical antonym to mysqli_set_charset and people wanting to know the name of currently selected character set should use mysqli_character_set_name ===== Backward Incompatible Changes ===== For PHP 8.6 additional deprecation notices will be emitted. The actual removal of the affected functionality will happen no earlier than PHP 9. ===== Removed from this proposal ===== The following entries were originally added to this proposal and then dropped.