rfc:deprecations_php_7_1

This is an old revision of the document!


PHP RFC: Deprecations for PHP 7.1

Introduction

This is a draft RFC for multiple deprecations targeting PHP 7.1. The RFC proposes to deprecate the listed functionality in PHP 7.1 and remove it no later than in PHP 8.0.

The following list provides a short overview of the functionality targeted for deprecation, while more detailed explanation is provided in the Proposal section:

  • __autoload
  • $php_errormsg
  • create_function()
  • rand(), srand() and getrandmax()
  • mbstring.func_overload
  • (unset) cast

Proposal

__autoload

The magic __autoload function has been superseded by spl_autoload_register in PHP 5.1 and its use discouraged in the documentation. One primary advantage of spl_autoload_register() is the ability to provide multiple chained autoloaders, thus easing library interoperability. Both mechanism are mutually exclusive, i.e. code using __autoload() cannot interoperate with code using spl_autoload_register(). As the latter is much more commonly used and also employed by Composer, the __autoload() mechanism has only very limited applicability nowadays.

Proposed action: A deprecation notice is thrown when a global function with name __autoload() is encountered during compilation.

$php_errormsg

The $php_errormsg variable is created in the local scope whenever a non-fatal error is thrown, if the track_errors ini setting is enabled (disabled by default) and the error has not been consumed by an error handler.

Apart from being ini-dependent language behavior, this behavior is highly magic and the error_get_last function provides a cleaner way of retrieving the last error. Since PHP 7 additionally the error_clear_last function is available, thus covering the last possible use-cases for $php_errormsg without magic scope manipulation.

Proposed action: A deprecation notice is thrown if the track_errors ini setting is enabled.

create_function()

create_function() is a thin wrapper around the eval() language construct, allowing the creation of a function with a generated function name and the argument list and body code provided as string arguments. Before the introduction of closures in PHP 5.3 it provided a way to create something akin to lambda functions.

Due to the nature of its operation create_function(), apart from being a potential source of security issues, has very bad performance and memory usage characteristics and the use of real closures is in every way preferable.

Proposed action: Mark the function as deprecated, thus issuing a deprecation notice on every call.

rand(), srand() and getrandmax()

The rand() function exposes the libc random number generator to PHP. The output and quality of this random number generator is system dependent. Notably, on Windows rand() can only generate at most 32767 unique values for any value range (if the value range includes more than 32767 numbers, some numbers will never be returned). Furthermore Windows uses a very low quality linear congruential generator with bad statistical properties (it's so bad you can see the non-uniformity with the naked eye).

As alternative, PHP provides mt_rand(), which is based on the 32-bit MT19937 algorithm. While not ideal (it generates at most 2147483647 unique values, even on 64-bit platforms), mt_rand() is strictly superior to rand() and does not have a platform dependence. It should always be preferred over rand().

The corresponding seeding function is srand() and getrandmax() returns the maximum number returned by the underlying generator. If rand() is deprecated, these should be deprecated as well.

Proposed action: Mark all three functions as deprecated, thus issuing a deprecation notice on every call.

Alternative action: Alias rand() etc. to the corresponding mt_*() functions. We may want to do some other changes do our non-crypto PRNG functionality at the same time, see http://markmail.org/message/gxjpvmvguhpni5zu.

mbstring.func_overload

The mbstring.func_overload ini setting allows replacing a certain subset of string functions with analogs from the mbstring extension. For example strlen() will no longer return the length of a string in bytes, instead it will return the length in code points according to the currently selected internal encoding.

This implies that code using mbstring.func_overload is incompatible with practically all other code, which is written under the assumption that basic string operations work normally. Some libraries outright forbid func_overload (e.g. Symfony), others will break in more subtle ways. Code that wants to support func_overload needs to conditionally switch between ordinary string functions and mbstring functions with 8bit encoding (however only cryptography libraries normally bother to do this).

In a previous discussion on this topic the consensus was to deprecate this functionality. The original author of the extension also recommended this action.

Proposed action: Throw a deprecation notice if mbstring.func_overload is set to a non-zero value.

Tracking bug: #65785

(unset) cast

The (unset) cast casts a value to null. This means that (unset) expr is simply an expression that always returns null and has no other side effects. Apart from being useless, this behavior is also confusing, as many people reasonably assume that (unset) $a will behave similarly to unset($a), while in truth it does no such thing.

Proposed action: Throw a deprecation notice if an (unset) cast is encountered in the parser. No deprecation notice is thrown from the lexer (so that token_get_all continues working as is).

Backward Incompatible Changes

For PHP 7.1 additional deprecation notices will appear. For PHP 8.0 the previously deprecated functionality will no longer be available.

Proposed Voting Choices

Each of the bullet points above will get a separate vote. All votes will require a 2/3 supermajority, independently of whether they are language changes or not.

Patches and Tests

The patches for these deprecations are for the most part trivial, as such they will be provided once the RFC is accepted (or portions of it).

Suggested deprecations

The following list contains various suggested deprecations that may or may not be included in this RFC (TODO section).

  • The (binary) cast and b“” string syntax. Those were added for forward compatibility with PHP 6, which has been discontinued.
  • The "${varName}", "${varName['offset']}" and "${expr}" alternative string interpolation syntaxes. These can be replaced by the more obvious and consistent "{$varName}", "{$varName['offset']}" and "{${expr}}". (Maybe leave the latter? That one is a bit awkward.)
  • The alternative parameter order for implode(). Standard order is string, array, but array, string is also allowed for historic reasons.
  • fputcsv etc. have been suggested, because they don't conform to the CSV standard. I think it's better to improve the implementation instead.
  • convert_cyr_string, as the same can be done with mb_convert_encoding or iconv.
  • Calling parse_str without the second parameter. This will put the result into the local symbol table.
  • get_magic_quotes_gpc, as it's pretty useless by now.
  • allow_url_include ini option.
  • hebrevc as it's just hebrev + nl2br.
  • sizeof, which is an alias of count.
  • Second argument to spl_autoload.

Rejected deprecations

The following section lists features that have been suggested for deprecation, but have not been included in this RFC for the outlined reasons.

$http_response_header

The $http_response_header variable is created in the local scope if an HTTP request is performed, for example through file_get_contents(). It contains an array of HTTP response headers.

The motivations for removing this functionality are similar to those of $php_errormsg, so it would seem reasonable to deprecate them at the same time. However, unlike $php_errormsg there exist no simple alternatives to $http_response_header. The get_headers function returns only the headers, but not the response body. Getting both requires, to my knowledge, a combination of fopen(), stream_get_contents() and reading the wrapper_data from stream_get_meta_data().

Changelog

  • 2016-02-19: Added mbstring.func_overload
  • 2016-02-18: Added getrandmax()
rfc/deprecations_php_7_1.1455891738.txt.gz · Last modified: 2017/09/22 13:28 (external edit)