rfc:deprecations_php_8_5

PHP RFC: Deprecations for PHP 8.5

Introduction

The RFC proposes to deprecate the listed functionality in PHP 8.5 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:

  • Deprecate key_length parameter of openssl_pkey_derive()
  • Deprecate PDO's 'uri:' scheme
  • Deprecate PDO::ERRMODE_WARNING error mode
  • Deprecate intl.error_level INI setting
  • Deprecate Reflection*::setAccessible()
  • Deprecate FILTER_DEFAULT constant
  • Make $filter parameter mandatory for filter_*() functions
  • Deprecate FILTER_CALLBACK filter
  • Deprecate the docref_root and docref_ext INI directives
  • Deprecate the error_prepend_string and error_append_string INI directives
  • Deprecate the report_memleaks INI directive
  • Deprecate the register_argc_argv INI directive
  • Formally deprecate mysqli_execute
  • Deprecate __construct() and __destruct() in interfaces
  • Deprecate semicolon after case in switch statement
  • Deprecate the $exclude_disabled parameter of get_defined_functions()
  • Deprecate building ext/ldap against Oracle LDAP
  • Deprecate passing null to readdir(), rewinddir(), and closedir()
  • Deprecate the $context parameter for finfo_buffer()
  • Deprecate finfo_close()
  • Deprecate xml_parser_free()
  • Deprecate curl_close()
  • Deprecate curl_share_close()
  • Deprecate imagedestroy()
  • Deprecate DATE_RFC7231 and DateTimeInterface::RFC7231
  • Deprecate ArrayObject with objects
  • Deprecate __debugInfo() returning null
  • Deprecate constant redeclaration
  • Deprecate Closure binding issues

Proposal

Each feature proposed for deprecation is voted separately and requires a 2/3 majority. All votes refer to deprecation in PHP 8.5 and removal in PHP 9 (except where otherwise noted).

Deprecate key_length parameter of openssl_pkey_derive()

This parameter is useless and confusing for users. It just truncates length for ECDH but does nothing or fails for increasing lengths and DH truncation. This was raised during the security audit.

See: https://github.com/php/doc-en/pull/3789

Deprecate PDO's 'uri:' scheme

Deprecate PDO::ERRMODE_WARNING error mode

TODO: Warnings are a weird mixture of exceptions, and setting the error code.

Deprecate intl.error_level INI setting

TODO: Similar to PDO::ERRMODE_WARNING where intl.use_exceptions should be preferred instead.

Deprecate Reflection*::setAccessible()

Deprecate FILTER_DEFAULT constant

The FILTER_DEFAULT constant is an alias for the FILTER_UNSAFE_RAW constant. This has been the case since at least PHP 5.3. This is confusing and seems to indicate that it corresponds to the filter set by the filter.default INI setting. Moreover, this INI setting was deprecated in PHP 8.1.

As this constant is confusing and misleading, we propose to deprecate it.

Make $filter parameter mandatory for filter_*() functions

The filter_*() functions do not require passing the $filter parameter, the default value of it is FILTER_DEFAULT which is an alias for the FILTER_UNSAFE_RAW filter. This filter does nothing if no flags are provided. This behaviour is indicative of a bug, therefore, we propose to make the $filter argument mandatory and emit a deprecation notice if the default value is used.

Deprecate FILTER_CALLBACK filter

The FILTER_CALLBACK filter allows providing a function to call on the value to filter. This makes little sense as one can pass the value to filter directly to the function instead of passing by the filter extension.

Similarly, to filter an array of values, it is easier and more intuitive to use the array_map() function rather than the filter extension.

As such, we propose to deprecate this filter.

Deprecate filter_input(), filter_input_array(), and filter_has_var()

The filter_input() and filter_input_array() functions operate on the original values provided by the SAPI that populate the superglobals for $_GET, $_POST, $_SERVER, $_ENV, and $_COOKIE.

This means that modification to any entry of the superglobal will not be used when calling these functions. This is showcased by the following PHPT test:

--TEST--
filter_input() filter with superglobal modified
--EXTENSIONS--
filter
--GET--
a=hello
--FILE--
<?php
 
var_dump($_GET);
$f1 = filter_input(INPUT_GET, "a", FILTER_CALLBACK, ['options' => fn (string $s) => $s === "world"]);
var_dump($f1);
 
$_GET['a'] = "world";
var_dump($_GET);
$f2 =filter_input(INPUT_GET, "a", FILTER_CALLBACK, ['options' => fn (string $s) => $s === "world"]);
var_dump($f2);
var_dump($_GET);
 
?>
--EXPECT--
array(1) {
  ["a"]=>
  string(5) "hello"
}
bool(false)
array(1) {
  ["a"]=>
  string(5) "world"
}
bool(false)
array(1) {
  ["a"]=>
  string(5) "world"
}

As it is easy and straight forward to have the same behaviour by using filter_var($_GET['a'], /* other params */) and filter_var_array($_GET, /* other params */), we propose to deprecate filter_input() and filter_input_array().

As filter_has_var() is effectively equivalent to array_key_exists(), but has the same caveat as the two previous functions, we propose to also deprecate this function.

Deprecate the docref_root and docref_ext INI directives

Both of these INI settings allow overriding the output of HTML diagnostic errors (warning, notice, deprecations, etc.) to change the base URL and file extension for the clickable links pointing to functions and/or INI settings in error messages generated by calls to php_error_docref().

This is a debug feature and had some value when the php.net documentation had mirrors, considering those have been retired, their use is now limited.

As such, we propose deprecating those two INI settings.

Deprecate the error_prepend_string and error_append_string INI directives

Both of these INI settings allow overriding the output of HTML diagnostic errors (warning, notice, deprecations, etc.) to prepend or append HTML before the generated HTML of these diagnostic errors.

This is a development and debugging feature which seems somewhat questionable and of limited use.

As such, we propose deprecating those two INI settings.

Deprecate the report_memleaks INI directive

This INI directive allows to suppress ZendMM memory leaks in debug builds of PHP. This “feature” is highly questionable, as memory leaks should be fixed the moment they are made aware of. Because this cannot affect production builds of PHP we propose deprecating this INI setting.

Deprecate the register_argc_argv INI directive

This INI directive tells PHP whether to declare the argv & argc variables. On the CLI, phpdbg and embed SAPIs it is forced to On. It defaults to Off on other SAPIs. This setting is dangerous on HTTP SAPIs because it allows defining the value of the argv/argc variables from the query string. This is almost always unwanted and certainly unexpected. It can lead to security issues if one reads argv/argc from an HTTP apps while not being aware of this behavior.

We propose to deprecate this INI setting and make in default to Off in PHP 8.5, then to hardcode it to Off for all non-CLI-related SAPIs on PHP 9 (while keeping it hardcoded to On for CLI-related ones).

Formally deprecate mysqli_execute

Deprecate __construct() and __destruct() in interfaces

Deprecate semicolon after case in switch statement

It is possible to terminate case statements with a semicolon instead of the standard colon:

switch ($value) {
    case 'foo';
    case 'bar':
    case 'baz';
        echo 'foo, bar, or baz';
        break;
    default;
        echo 'Other';
}

This syntax is a leftover from PHP/FI 2, where nearly all lines including if conditions and case statements were terminated by a semicolon. 1 2

There isn't a need for this syntax to exist anymore, and very few PHP developers are even aware of its existence. In the top 1000 Composer packages, zero out of 35,777 total case statements are using the alternate syntax (as of 2024-11-27).

Case statements followed by a semicolon can cause confusion, as a developer may think they behave differently in some way from regular case statements (e.g. preventing fallthrough), when they do not.

Therefore, we propose to deprecate terminating case statements with a semicolon.

Deprecate the $exclude_disabled parameter of get_defined_functions()

As of PHP 8.0.0, functions that are disabled via the disable_functions INI setting are simply removed from the function table. As such, this parameter no longer has any effect and is pointless. Therefore, we propose to deprecate it.

Deprecate building ext/ldap against Oracle LDAP

Building ext/ldap against Oracle LDAP had been supported, and is theoretically still supported, but is apparently broken for a while. The Oracle LDAP implementation is part of Oracle Instant Client, and uses an older LDAP API; apparently, there are no plans for updating this. So users are almost certainly better off to build against OpenLDAP (and if they need OCI8, to build that as shared library, and load after ext/ldap).

Therefore we supposed to deprecate building ext/ldap against Oracle LDAP.

It should be noted that the ldap_connect_wallet() function, available only as of PHP 8.3, would also be part of the deprecation, as well as other existing Oracle LDAP specific features.

Deprecate passing null to readdir(), rewinddir(), and closedir()

TODO: This assumes the last open directory stream opened with opendir() or dir() we have deprecated such usages previous (see mysql and pgsql).

Deprecate the $context parameter for finfo_buffer()

This parameter is unused, and the only reason it exists in the first place is because the implementation of it was delegated to a “god” C function that also was handling finfo_file() which does use the provided context.

As this parameter is not useful for this function it should be deprecated.

Deprecate finfo_close()

Since the migration of the fileinfo extension from resources to objects in PHP 8.1, this function has been a no-op.

As the function is not needed anymore, it should be deprecated.

Deprecate xml_parser_free()

Since the migration of the xml extension from resources to objects in PHP 8.0, this function has been a no-op.

As the function is not needed anymore, it should be deprecated.

Deprecate curl_close()

Since the migration of the cURL extension from resources to objects in PHP 8.0, this function has been a no-op.

As the function is not needed anymore, it should be deprecated.

Deprecate curl_share_close()

Since the migration of the cURL extension from resources to objects in PHP 8.0, this function has been a no-op.

As the function is not needed anymore, it should be deprecated.

Deprecate imagedestroy()

Since the migration of the GD extension from resources to objects in PHP 8.0, this function has been a no-op.

As the function is not needed anymore, it should be deprecated.

Deprecate DATE_RFC7231 and DateTimeInterface::RFC7231

Because the implementation of the constant contains the timezone `GMT` designation, the format of date will always show the `GMT` timezone, despite the real timezone of the instance of `DateTimeInterface`. This may lead to unwanted results.

The implementation of this constant was a mistake, as this was described as bug. This wasn't bug, but a feature request: https://github.com/php/php-src/pull/2450

Implementation: https://github.com/php/php-src/pull/12989

Deprecate ArrayObject with objects

Documentation currently says

Wrapping objects with this class is fundamentally flawed, and therefore its usage with objects is discouraged.

TODO explain the history of ArrayObject-related bugs being closed

https://wiki.php.net/rfc/container-offset-behaviour#arrayobject

Deprecate __debugInfo() returning null

Since the __debugInfo() magic method was added, it has been documented as needing to return an array (see original implementation) in the error message if you return a non-array and non-null value.

However, null has been silently treated the same as an empty array.

This can result in confusion about if null means something different. Accordingly, we propose to deprecate returning null from __debugInfo() magic methods.

Deprecate constant redeclaration

In PHP 8, attempting to declare a constant that already existing was changed to emit a warning rather than just a notice. We propose to elevate this in PHP 8.5 to a deprecation (and in 9.0 to an error).

Redeclaring a constant can lead to invalid assumptions, specifically if a developer assumes that the declaration will succeed they may assume a constant has one value when it actually has a different value.

Deprecate closure binding issues

When trying to bind a Closure object, multiple issues can potentially be raised, but only as warnings:

  • “Cannot bind an instance to a static closure”
  • “Cannot bind method %s::%s() to object of class %s” - for trying to change the type of object bound to
  • “Cannot unbind $this of method”
  • “Cannot unbind $this of closure using $this”
  • “Cannot bind closure to scope of internal class %s”
  • “Cannot rebind scope of closure created from function”
  • “Cannot rebind scope of closure created from method”

We propose to elevate these in PHP 8.5 to deprecations (and in 9.0 to errors).

Backward Incompatible Changes

For PHP 8.5 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.

rfc/deprecations_php_8_5.txt · Last modified: 2025/05/05 18:42 by daniels