PHP RFC: Deprecations for PHP 8.5
- Date: 2024-09-26
- Authors:
- Gina Peter Banyard girgias@php.net
- Christoph M. Becker cmb@php.net
- Daniel Scherzer daniel.e.scherzer@gmail.com
- Theodore Brown theodorejb@php.net
- Jorg Sowa jorg.sowa@gmail.com
- David Carlier devnexen@gmail.com
- Status: Draft
- Implementation: TBD
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 ofopenssl_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 forfilter_*()
functions - Deprecate FILTER_CALLBACK filter
- Deprecate the
docref_root
anddocref_ext
INI directives - Deprecate the
error_prepend_string
anderror_append_string
INI directives - Deprecate the
report_memleaks
INI directive - Deprecate the
register_argc_argv
INI directive - Formally deprecate mysqli_execute
- Formally deprecate socket_set_timeout
- Deprecate
__construct()
and__destruct()
in interfaces - Deprecate semicolon after
case
in switch statement - Deprecate the
$exclude_disabled
parameter ofget_defined_functions()
- Deprecate building ext/ldap against Oracle LDAP
- Deprecate the
$context
parameter forfinfo_buffer()
- Deprecate
finfo_close()
- Deprecate
xml_parser_free()
- Deprecate
curl_close()
- Deprecate
curl_share_close()
- Deprecate
imagedestroy()
- Deprecate
DATE_RFC7231
andDateTimeInterface::RFC7231
- Deprecate
ArrayObject
with objects - Deprecate
SplObjectStorage::contains()
,SplObjectStorage::attach()
, andSplObjectStorage::detach()
- Deprecate using values of type
null
,bool
, andfloat
as array offsets and when callingarray_key_exists()
- Deprecate
__debugInfo()
returning null - Deprecate constant redeclaration
- Deprecate
Closure
binding issues - Deprecate non-standard cast names
- Deprecate passing
spl_autoload_call()
tospl_autoload_unregister()
- Enact follow-up phase of the “Path to Saner Increment/Decrement operators” RFC
- Remove the
disable_classes
INI setting - Deprecate the
$http_response_header
predefined variable - Deprecate driver specific
PDO
constants and methods - Deprecate
Pdo_Pgsql::PGSQL_TRANSACTION_IDLE
,Pdo_Pgsql::PGSQL_TRANSACTION_ACTIVE
,Pdo_Pgsql::PGSQL_TRANSACTION_INTRANS
,Pdo_Pgsql::PGSQL_TRANSACTION_INERROR
andPdo_Pgsql::PGSQL_TRANSACTION_UNKNOWN
- Deprecate attributes applying to multiple class properties/constants
- Deprecate backticks
`
as an alias for shell_exec
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.
Deprecate PDO's 'uri:' scheme
- Author: Tim Düsterhus timwolla@php.net
PDO supports a uri:
DSN scheme that does not refer to a database driver named “uri” but instead is an indication to read the actual DSN from the specified URI, including remote stream wrappers, such as HTTP URIs.
While this feature might appear to be useful to make it easier for environment-specific configuration of an application, the username and password notably are not part of the DSN, which would require a separate configuration mechanism and which point the actual DSN could use it as well. Similarly authentication via TLS certificates with the MySQL driver would require specifying the certificate and private key as the $options
.
In case of remote stream wrappers, the feature can be actively dangerous, unless the URL referenced is 100% trustworthy, since the username and password for the database might be sent to an untrusted database servers. In case of the SQLite PDO driver, a remote URL might enable access to arbitrary SQLite files on the server. Furthermore remote stream wrappers might result in performance-bottlenecks, since the file is requested for every single connection.
If this feature is somehow exactly what is desired, it can easily replicated in userland as follows (while preserving the main semantics of only looking at the first line):
Deprecate PDO::ERRMODE_WARNING error mode
- Author: Gina Peter Banyard girgias@php.net
PDO can be set to report errors in 3 different ways:
PDO::ERRMODE_SILENT
PDO::ERRMODE_WARNING
PDO::ERRMODE_EXCEPTION
In silent mode, PDO will proceed if an error has occured within a PDO statement or PDO instance, and set the error code and info so that it can be queried manually. This allows for a more hands on approach to error handling.
In exception mode, PDO will instead throw a PDOException
whenever an error occurs,
and unwind the stack unless it the exception is caught via a catch
block.
This is a more of a hands off approach as error handling doesn't need to be done after each method call of a PDO or PDO statement instance.
This mode has been the default since PHP 8.0.
In warning mode, PDO will behave similarly as if set in silent mode,
but also raise an E_WARNING
similarly to how the exception mode behaves.
As such this mode is a bit non-sensical as it is both a hands on and hands off approach to error handling.
Moreover, an E_WARNING
may be promoted to an exception via an error handler set via set_error_handler()
,
something that might not be expected by code written with PDO::ERRMODE_SILENT
in mind.
As such we propose to deprecate the PDO::ERRMODE_WARNING
constant and recommend users either use the silent or exception mode.
Deprecate intl.error_level INI setting
- Author: Gina Peter Banyard girgias@php.net
Error handling within the Intl extension is handled by two ini settings:
- The
intl.use_exceptions
INI setting which determines if errors are report by throwing anIntlException
- The
intl.error_level
INI setting allows to set which type of error level should used, typically one of theE_*
error constants.
Moreover, it is possible to enable both exceptions and use a non-zero error level, in which case the error is emitted first.
This means that it can be “caught” via an error handler set with set_error_handler()
first and be promoted to an exception different than IntlException
.
However, more concerningly is that the error level could be set to E_ERROR
which would trigger a bailout of the PHP VM.
PHP's bailout mechanism is generaly reserved for severe engine failures, such as being unable to allocate memory.
There are multiple issues with bailouts which are described in detail in the "Issues with fatal errors" section of the Exceptions in the engine (for PHP 7) RFC. Some of them are:
finally
blocks are not executed- Destructors are not executed
- Memory may not be freed
As this INI setting has some of the same pitfalls as the PDO::ERRMODE_WARNING
constant and can cause bailouts,
we propose deprecating this INI setting, meaning setting it to any value different than 0
will raise an E_DEPRECATED
diagnostic.
Deprecate Reflection*::setAccessible()
- Author: Tim Düsterhus timwolla@php.net
The “Make reflection setAccessible() no-op” RFC in PHP 8.1 made the Reflection*::setAccessible()
methods a noop. However it did not deprecate the methods to simplify cross-version compatibility.
Since PHP 8.0, which is the last version where the methods did anything, is already EOL and PHP 8.1, which introduced the change will be EOL shortly after the release of PHP 8.5, it seems reasonable to deprecate the methods to make users aware that they have no effect (especially for calls to ->setAccessible(false)
) and to encourage users to remove them.
If compatibility with PHP 8.0 or earlier is desired, the deprecation can be suppressed with @
or alternatively the call to ->setAccessible()
can be guarded by an if (PHP_VERSION_ID < 80100)
check.
We therefore propose to add:
#[\Deprecated(since: '8.5', message: "as this method does nothing")]
to the signature.
Deprecate FILTER_DEFAULT constant
- Author: Gina Peter Banyard girgias@php.net
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
- Author: Gina Peter Banyard girgias@php.net
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
- Author: Gina Peter Banyard girgias@php.net
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()
- Author: Gina Peter Banyard girgias@php.net
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
- Author: Gina Peter Banyard girgias@php.net
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
- Author: Gina Peter Banyard girgias@php.net
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
- Author: Gina Peter Banyard girgias@php.net
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
- Author: Nicolas Grekas nicolas.grekas@php.net
This INI directive tells PHP whether to declare the argv & argc variables. On the CLI, phpdbg and embed SAPIs it is forced to On. On other SAPIs, it defaults to On in the C code but is set to Off in the default php.ini files. 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
- Author: Tim Düsterhus timwolla@php.net
mysqli_execute()
is an alias of mysqli_stmt_execute()
and already marked as deprecated in the documentation (“mysqli_execute() is deprecated and will be removed.”). Its name is misleading since it operates on an mysqli_stmt
object, rather than an mysqli
object, leading to possible confusion with the mysqli_execute_query()
function added in PHP 8.2 that does operate on an mysqli
object.
We therefore propose to add:
#[\Deprecated(since: '8.5', message: "use mysqli_stmt_execute() instead")]
to the signature.
Formally deprecate socket_set_timeout
- Author: Tim Düsterhus timwolla@php.net
socket_set_timeout()
is an alias of stream_set_timeout()
and already marked as deprecated in the documentation (“This function was previously called as set_socket_timeout() and later socket_set_timeout() but this usage is deprecated.”). Its name is misleading since it not part of the ext/sockets extension, which uses the socket_x()
prefix.
We therefore propose to add:
#[\Deprecated(since: '8.5', message: "use stream_set_timeout() instead")]
to the signature.
Deprecate __construct() and __destruct() in interfaces
- Author: Tim Düsterhus timwolla@php.net
TODO: https://phpc.social/@dseguy/113476785631597024 / https://github.com/php/php-src/issues/16077
Deprecate semicolon after case in switch statement
- Author: Theodore Brown theodorejb@php.net
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). Edit: as of 2025-06-02 there are still zero usages of the alternate syntax in the top 1000 packages (out of 29,858 total case statements).
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()
- Author: Gina Peter Banyard girgias@php.net
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
- Author: Christoph M. Becker cmb@php.net
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()
- Author: Gina Peter Banyard girgias@php.net
The readdir()
, rewinddir()
, and closedir()
functions accept null
as the value for the $dir_handle
, in which case it will used the previously opened directory stream opened with opendir()
.
This is global state that can change if another call to opendir()
is made, which could happen by calling a library function, and leading to spooky action at a distance.
Prior extensions and functions that behaved this way have been deprecated, most notably the original ext/mysql extension and more recently the ext/pgsql functions that were overloaded were deprecated in PHP 8.1
As such, we propose deprecating passing null
to readdir()
, rewinddir()
, and closedir()
.
Deprecate the $context parameter for finfo_buffer()
- Author: Gina Peter Banyard girgias@php.net
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()
- Author: Daniel Scherzer daniel.e.scherzer@gmail.com
- Implementation: https://github.com/php/php-src/pull/18396
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. We therefore propose to add:
#[\Deprecated(since: '8.5', message: "as this method does nothing")]
to the signature.
Deprecate xml_parser_free()
- Author: Daniel Scherzer daniel.e.scherzer@gmail.com
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. We therefore propose to add:
#[\Deprecated(since: '8.5', message: "as this method does nothing")]
to the signature.
Deprecate curl_close()
- Author: Daniel Scherzer daniel.e.scherzer@gmail.com
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. We therefore propose to add:
#[\Deprecated(since: '8.5', message: "as this method does nothing")]
to the signature.
Deprecate curl_share_close()
- Author: Daniel Scherzer daniel.e.scherzer@gmail.com
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. We therefore propose to add:
#[\Deprecated(since: '8.5', message: "as this method does nothing")]
to the signature.
Deprecate imagedestroy()
- Author: Daniel Scherzer daniel.e.scherzer@gmail.com
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. We therefore propose to add:
#[\Deprecated(since: '8.5', message: "as this method does nothing")]
to the signature.
Deprecate DATE_RFC7231 and DateTimeInterface::RFC7231
- Author: Jorg Sowa jorg.sowa@gmail.com
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
- Author: Daniel Scherzer daniel.e.scherzer@gmail.com
- Author: Gina Peter Banyard girgias@php.net
ArrayObject
allows using an instance of a class as a “backing array” rather than the more typical behaviour of using a standard PHP array.
However the way this feature was designed breaks nearly every single expectation and invariant around objects not just for users, but also the engine.
It allows accessing private and protected properties from the global scope, write multiple times to readonly
properties, write values of invalid types to typed properties, misshandles isset()
and empty()
, allows writing dynamic properties without issuing any warning , and can even add dynamic properties to internal classes that ban dynamic properties, doesn't call the magic __get()
and __set()
methods, and probably some other hidden issues.
One example to showcase some of the issues is the following:
<?php class T { private readonly int $p; public string $p2; public function getP() { return $this->p; } } $o = new T(); $a = new ArrayObject($o); $a["\0T\0p"] = 'str'; var_dump($o->getP()); $a["\0T\0p"] = 'modified'; var_dump($o->getP()); var_dump(isset($a["p2"])); var_dump($o->p2);
which outputs the following:
string(3) "str" string(8) "modified" bool(true) Fatal error: Uncaught Error: Typed property T::$p2 must not be accessed before initialization in php-wasm run script:%d Stack trace: #0 {main} thrown in php-wasm run script on line %d
As such we recommend deprecating passing an object to the constructor of ArrayObject
.
Deprecate SplObjectStorage::contains(), SplObjectStorage::attach(), and SplObjectStorage::detach()
- Author: Gina Peter Banyard girgias@php.net
This is lifted from the Improve language coherence for the behaviour of offsets and containers RFC as it is time sensitive.
The following three methods are aliases for methods defined by ArrayAccess
, namely:
SplObjectStorage::contains()
is an alias forSplObjectStorage::offsetExists()
SplObjectStorage::attach()
is an alias forSplObjectStorage::offsetSet()
SplObjectStorage::detach()
is an alias forSplObjectStorage::offsetUnset()
However, extending `SplObjectStorage` and overwriting one of the alias methods does not modify the behaviour of using the offset access operators. Meaning that it is possible to have an asymetry between using methods calls and the overloaded offset access operators.
As such we propose deprecating the method aliases in favour of using the ArrayAccess
methods.
Deprecate using values of type null, bool, and float as array offsets and when calling array_key_exists()
- Author: Gina Peter Banyard girgias@php.net
This is lifted from the Improve language coherence for the behaviour of offsets and containers RFC as it is time sensitive.
How offsets are handled in PHP is rather unintuitive and not consistent with many other areas of the language.
Notably an offset of null
is type juggled to the empty string ""
rather than 0
,
contrasting with how values of type bool
, float
, and resources
are cast to int
.
Which is even more surprising that the other operators that accept both string and int are bitwise operators and they throw a type error when attempting to use null
with a value of type string
.
Moreover, invalid types for string offsets always warn, which is not the case for array offsets (except when using a resource).
As such we propose deprecating using values of type null
, bool
, and float
as array offsets and when calling array_key_exists()
Deprecate __debugInfo() returning null
- Author: Daniel Scherzer daniel.e.scherzer@gmail.com
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
- Author: Daniel Scherzer daniel.e.scherzer@gmail.com
In PHP 8, attempting to declare a constant that already existing was changed to emit a warning rather than just a notice. Since a warning is considered stronger than a deprecation, the error code should not change, but we propose that
- The behavior trigger an error in PHP 9
- The warning messages in 8.5+ indicate that the behavior will trigger an error in PHP 9
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
- Author: Daniel Scherzer daniel.e.scherzer@gmail.com
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”
Since a warning is considered stronger than a deprecation, the error code should not change, but we propose that
- The behavior trigger errors in PHP 9
- The warning messages in 8.5+ indicate that the behavior will trigger errors in PHP 9
Deprecate non-standard cast names
- Author: Gina Peter Banyard girgias@php.net
This supercedes the following inactive RFC Deprecate Inconsistent Cast Names.
We propose to deprecate the following non-standard cast names:
(integer)
(boolean)
(double)
This is inline how using non-standard names for built-in types emits a “confusable” warning at compile time, for example:
<?php function foo(integer $x) { }
Causes the following warning to be emitted:
Warning: “integer” will be interpreted as a class name. Did you mean “int”? Write “\integer” to suppress this warning
For consistency reasons with the rest of the language we propose to deprecate such casts and recommend using the standard ones.
Deprecate passing spl_autoload_call() to spl_autoload_unregister()
- Author: Gina Peter Banyard girgias@php.net
The spl_autoload_register()
function allows registering a callable to find classes during autoloading.
Naturally it prevents passing the spl_autoload_call()
as a callback, as this would be non-sensical.
However, the spl_autoload_unregister()
function, which is used to remove a callback from the autoloading sequence does permit passing the spl_autoload_call()
function as a callback, in which case all autoloading callbacks are removed.
This behaviour is undocumented and frankly baffling, as such we propose to deprecate passing spl_autoload_call()
to spl_autoload_unregister()
.
If there is a need to remove all autoloading functions it is possible to do so via the following obvious method:
foreach (spl_autoload_functions() as $fn) { spl_autoload_unregister($fn); }
Enact follow-up phase of the "Path to Saner Increment/Decrement operators" RFC
- Author: Gina Peter Banyard girgias@php.net
The Path to Saner Increment/Decrement operators RFC delayed the deprecation of the PERL string increment feature so that users could have time to migrate to the new str_increment()
function introduced in PHP 8.3.
As there have been two minor versions to allow this migration we now proposed to enact the following delayed deprecation from the RFC:
Deprecate using the increment operator with non-numeric strings.
Remove disable_classes INI setting
- Author: Gina Peter Banyard girgias@php.net
This supercedes the following inactive RFC Remove disable_classes INI setting.
The disable_classes
INI setting is fundamentally useless and causes various issues in the engine, as using it will result in unexpected states for the engine to deal with.
Only internal classes can be disabled, which brings the following observation. On a minimal build of PHP, with only the mandatory extensions enabled, there are 148 classes/interfaces/traits defined. [2]
Other than a specific subset of classes defined in the SPL extension, disabling any of these classes will cause issues within the engine. Moreover, the subset of SPL classes that could be disabled are not a security concern.
Therefore, any other class that can be disabled must come from an extension that can be disabled altogether. And “disabling” a class from an extension without disabling said extension will, other than rendering it useless, cause various issues that the extension is not prepared to handle as they expect the classes they defined to exist.
If a hosting provider is concerned about an extension, then it should not enable it in the first place. Not break it ad hoc.
Considering the above, the usefulness of this feature has always been dubious.
This is in stark contrast to the disable_functions
INI setting, which can be used to selectively remove functionality of an extension without breaking it overall.
What makes this setting particularly broken is that it does not unregister the class, it only overwrites the create CE handler to emit a warning and purge the properties and function hash tables.
This leads to various use after free, segfaults, and broken expectations for the engine and extensions which define said classes.
On top of that, it is possible to actually instantiate such a class (and even classes which actually disallow this like ext/imap
) in userland, and pass it to functions that are typed against said class without raising a TypeError.
However, when trying to do anything with said object, stuff is going to explode in countless ways.
The only usage we can find is within the Fuzzer SAPI to block instantiation of the InfiniteIterator
class so that it does not try to fuzz this class. This can be fixed by manually changing the create handler of the InfiniteIterator
CE to throw in the fuzzer initiation code.
As such we propose removing the disable_classes
INI setting.
Deprecate the $http_response_header predefined variable
- Author: Gina Peter Banyard girgias@php.net
This was initially slated for deprecation in PHP 8.1, however it was removed from the proposal as there were no practical alternatives for this functionality.
This was addressed in PHP 8.4 by adding the http_get_last_response_headers() function. As the usage of this predefined variable is small, at the time of the RFC introducing the new functions, 65 times. And it is possible to write cross version compatible code in the following way:
$content = file_get_contents('http://example.com/'); if (function_exists('http_get_last_response_headers')) { $http_response_header = http_get_last_response_headers(); } // Use $http_response_header as before
We propose deprecating using the $http_response_header
without having previously called http_get_last_response_headers()
Deprecate driver specific PDO constants and methods
- Author: Gina Peter Banyard girgias@php.net
With the acceptance and merging of the PDO driver specific sub-classes RFC, the recommended way to provide driver specific functionality is by creating a subclass of PDO with said functionality. As such we propose deprecating the overloaded PDO constants which are declared using the REGISTER_PDO_CLASS_CONST_LONG
macros and the overloaded PDO methods which are defined in the pgsql_driver.stub.php
and sqlite_driver.stub.php
files.
This means the following PDO constants would be deprecated:
PDO::DBLIB_ATTR_CONNECTION_TIMEOUT
PDO::DBLIB_ATTR_QUERY_TIMEOUT
PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER
PDO::DBLIB_ATTR_VERSION
PDO::DBLIB_ATTR_TDS_VERSION
PDO::DBLIB_ATTR_SKIP_EMPTY_ROWSETS
PDO::DBLIB_ATTR_DATETIME_CONVERT
PDO::FB_ATTR_DATE_FORMAT
PDO::FB_ATTR_TIME_FORMAT
PDO::FB_ATTR_TIMESTAMP_FORMAT
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY
PDO::MYSQL_ATTR_LOCAL_INFILE
PDO::MYSQL_ATTR_INIT_COMMAND
PDO::MYSQL_ATTR_MAX_BUFFER_SIZE
PDO::MYSQL_ATTR_READ_DEFAULT_FILE
PDO::MYSQL_ATTR_READ_DEFAULT_GROUP
PDO::MYSQL_ATTR_COMPRESS
PDO::MYSQL_ATTR_DIRECT_QUERY
PDO::MYSQL_ATTR_FOUND_ROWS
PDO::MYSQL_ATTR_IGNORE_SPACE
PDO::MYSQL_ATTR_SSL_KEY
PDO::MYSQL_ATTR_SSL_CERT
PDO::MYSQL_ATTR_SSL_CA
PDO::MYSQL_ATTR_SSL_CAPATH
PDO::MYSQL_ATTR_SSL_CIPHER
PDO::MYSQL_ATTR_SERVER_PUBLIC_KEY
PDO::MYSQL_ATTR_MULTI_STATEMENTS
PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT
PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY
PDO::ODBC_ATTR_USE_CURSOR_LIBRARY
PDO::ODBC_ATTR_ASSUME_UTF8
PDO::ODBC_SQL_USE_IF_NEEDED
PDO::ODBC_SQL_USE_DRIVER
PDO::ODBC_SQL_USE_ODBC
PDO::PGSQL_ATTR_DISABLE_PREPARES
PDO::PGSQL_TRANSACTION_IDLE
PDO::PGSQL_TRANSACTION_ACTIVE
PDO::PGSQL_TRANSACTION_INTRANS
PDO::PGSQL_TRANSACTION_INERROR
PDO::PGSQL_TRANSACTION_UNKNOWN
PDO::SQLITE_DETERMINISTIC
PDO::SQLITE_ATTR_OPEN_FLAGS
PDO::SQLITE_OPEN_READONLY
PDO::SQLITE_OPEN_READWRITE
PDO::SQLITE_OPEN_CREATE
PDO::SQLITE_ATTR_READONLY_STATEMENT
PDO::SQLITE_ATTR_EXTENDED_RESULT_CODES
And the following overloaded PDO methods would be deprecated:
PDO::pgsqlCopyFromArray()
PDO::pgsqlCopyFromFile()
PDO::pgsqlCopyToArray()
PDO::pgsqlCopyToFile()
PDO::pgsqlGetNotify()
PDO::pgsqlGetPid()
PDO::pgsqlLOBCreate()
PDO::pgsqlLOBOpen()
PDO::pgsqlLOBUnlink()
PDO::sqliteCreateAggregate()
PDO::sqliteCreateCollation()
PDO::sqliteCreateFunction()
Deprecate attributes applying to multiple class properties/constants
- Author: Daniel Scherzer daniel.e.scherzer@gmail.com
Multiple class properties or constants can be declared in a single declaration, e.g.
<?php #[Attribute] class Test {} class Foo { #[Test] public $bar, $baz; #[Test] public const BAR = 1, BAZ = 2; }
This can be confusing, because the attributes are added to all of the properties/constants in the declaration, not just the first.
Because of the potential for confusion, when attributes were added to compile-time constants in attributes-on-constants, adding attributes to multiple non-class constants at once was not allowed.
We now propose to deprecate the same confusing behavior for the existing cases of class properties/constants.
Deprecate backticks as an alias for shell_exec
- Author: Volker Dusch edorian@php.net
Backticks are a rarely used and somewhat unknown feature of PHP that can cause confusion and hide the need for error handling by not allowing access to exit codes.
- In code review, it's hard to spot the difference between
`
and'
at a glance. - JavaScript uses it for template strings, causing confusion between the syntax, even for more senior developers switching between the languages.
- It's not trivial to look up what the operator does.
- Refactoring efforts, even for complex calls, are minimal thanks to
<<<'NOWDOC'
. - It would eventually free up the backtick operator for future use.
- Simplifies the languages for humans, static analysis and other tooling.
- Hides the need for
escapeshellarg
more than other ways of executing shell code.
Therefore, we propose to deprecate the backtick operator.
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.