[PHP-DEV] [RFC] Deprecations for PHP 8.5

On 08.07.2025 at 01:30, Theodore Brown wrote:

Almost all of these were quickly fixed by sending a pull request.

See Deprecate alternate switch case syntax? - Externals, in particular Derick's reply.

I believe Derick was commenting specifically on using separate <?php ?> tags interleaved around
each switch, case, break, and endswitch statement (which there are no plans to deprecate). Based
on the follow-up replies from him and Tim, deprecating semicolon-terminated case statements
would not affect his xdebug.org site templates.

The use case we're talking about would be something like (indented to
avoid issues with Newsreaders):

  <?switch ($foo):?>
  <?case 1?>
  <p>1</p>
  <?break?>
  <?case 2?>
  <p>2</p>
  <?break?>
  <?endswitch?>

If that code wouldn't trigger a deprecation notice, fine. However, we
had apparently introduced an inconsistency then.

Note that I do not advocate writing such code, but I wouldn't be
surprised if such code exists in the wild, but even more suprised if
such code would be found in a Composer package.

Christoph M. Becker

We propose to deprecate the following non-standard cast names:

  • (integer)

  • (boolean)

  • (double)

  • (binary)

Hello,

Just wondering is this going to affect settype() function? There is already some disparity in that settype() supports integer/boolean/double but not binary type (and additionally supports null type).

On 06.07.2025 at 19:16, Tim Düsterhus wrote:

Nevertheless I found it important to point out that the deprecation
itself is not a breaking change, since it is a common theme that folks
incorrectly claim that "PHP X.Y broke my code", when it's just some
deprecation messages being emitted. The deprecation allows you to fix
the issue at hand at a pace you are comfortable with. As an example, if
the code in question is in the process of being replaced anyways, then
you don't need to do anything.

The RFC at hand states:

| The RFC proposes to deprecate the listed functionality in PHP 8.5 and
| remove it in PHP 9 (except where otherwise noted).

That *might* give users only a year to fix the deprecated features, what
might not match everybody's pace, though.

It seems to be prudent to reduce the number of deprecations for the
ultimate (and maybe the penultimate) minor version prior to a major
release. Of course, that would require us to plan ahead. :expressionless:

Christoph M. Becker

On Wednesday, 9 July 2025 at 08:17, Daikaras <webmaster@daikaras.lt> wrote:

We propose to deprecate the following non-standard cast names:

- (integer)
- (boolean)
- (double)
- (binary)

Hello,

Just wondering is this going to affect `settype()` function? There is already some disparity in that `settype()` supports `integer/boolean/double` but not `binary` type (and additionally supports `null` type).

I wasn't aware of the discrepencies with settype() so I added the deprecation of non-canonical type names to settype() as its own deprecation entry in the ext/standard section.
Thanks for bringing this to my attention!

Best regards,
Gina P. Banyard

Hi,

A possible reason for wanting to use the non-canonical names in settype(), is that those names are returned by gettype(). Fictional example (not intended to be reasonable, only illustrative):

function settype_from(&$a, &b) {
return settype($a, gettype($b));
}

Personally, I have used “integer”, etc. instead of “int”, etc., in settype() in the past, because those were the “canonical” (as I perceived) forms returned by gettype(). I have slowly fallen out of that habit in the years after I began to use scalar type declarations (introduced in PHP 7).

—Claude

···

On Wednesday, 9 July 2025 at 08:17, Daikaras webmaster@daikaras.lt wrote:

We propose to deprecate the following non-standard cast names:

  • (integer)

  • (boolean)

  • (double)

  • (binary)

Hello,

Just wondering is this going to affect settype() function? There is already some disparity in that settype() supports integer/boolean/double but not binary type (and additionally supports null type).

I wasn’t aware of the discrepencies with settype() so I added the deprecation of non-canonical type names to settype() as its own deprecation entry in the ext/standard section.
Thanks for bringing this to my attention!

Best regards,

Gina P. Banyard

On 7/10/2025 12:23 AM, Claude Pache wrote:

Le 9 juil. 2025 à 14:21, Gina P. Banyard <internals@gpb.moe> a écrit :

On Wednesday, 9 July 2025 at 08:17, Daikaras <webmaster@daikaras.lt> wrote:

We propose to deprecate the following non-standard cast names:

*
    |(integer)|
*
    |(boolean)|
*
    |(double)|
*
    |(binary)|

Hello,

Just wondering is this going to affect `settype()` function? There is already some disparity in that `settype()` supports `integer/boolean/double` but not `binary` type (and additionally supports `null` type).

I wasn't aware of the discrepencies with settype() so I added the deprecation of non-canonical type names to settype() as its own deprecation entry in the ext/standard section.
Thanks for bringing this to my attention!

Best regards,

Gina P. Banyard

Hi,

A possible reason for wanting to use the non-canonical names in settype(), is that those names are returned by gettype(). Fictional example (not intended to be reasonable, only illustrative):

function settype_from(&$a, &b) {
    return settype($a, gettype($b));
}

Personally, I have used "integer", etc. instead of "int", etc., in settype() in the past, because those were the “canonical” (as I perceived) forms returned by gettype(). I have slowly fallen out of that habit in the years after I began to use scalar type declarations (introduced in PHP 7).

—Claude

Oof, I didn't think of that. So this is a no go, IMO.

On Wednesday, 9 July 2025 at 22:26, Claude Pache <claude.pache@gmail.com> wrote:

Hi,

A possible reason for wanting to use the non-canonical names in settype(), is that those names are returned by gettype(). Fictional example (not intended to be reasonable, only illustrative):

function settype_from(&$a, &b) {
return settype($a, gettype($b));
}

Personally, I have used "integer", etc. instead of "int", etc., in settype() in the past, because those were the “canonical” (as I perceived) forms returned by gettype(). I have slowly fallen out of that habit in the years after I began to use scalar type declarations (introduced in PHP 7).

We are well aware of this "issue" and get_debug_type() was introduced in PHP 8 as a replacement for gettype() that returns the canonical names.
The one difference is that objects return the class name rather than "object".
I can add a deprecation of gettype() to nudge people to use get_debug_type() instead, if you think that's reasonable.

Best regards,
Gina P. Banyard

Hi

Am 2025-07-09 12:34, schrieb Christoph M. Becker:

The RFC at hand states:

| The RFC proposes to deprecate the listed functionality in PHP 8.5 and
| remove it in PHP 9 (except where otherwise noted).

That *might* give users only a year to fix the deprecated features, what
might not match everybody's pace, though.

Each PHP version is supported for 4 years by the PHP project [1], thus giving folks at least 4 years to handle each deprecation until they are forced to upgrade to a supported PHP version.

Best regards
Tim Düsterhus

[1] And possibly even longer by the various Linux distributions out there. As an example PHP 7.4 is still supported by Debian in the oldstable Bullseye branch and got its last update on 2025-03-19: Debian Package Tracker

On 10.07.2025 at 14:06, Tim Düsterhus wrote:

Am 2025-07-09 12:34, schrieb Christoph M. Becker:

That *might* give users only a year to fix the deprecated features, what
might not match everybody's pace, though.

Each PHP version is supported for 4 years by the PHP project [1], thus
giving folks at least 4 years to handle each deprecation until they are
forced to upgrade to a supported PHP version.

That point is moot for a lot of software where the developers are not
necessarily in control of which PHP version is used (e.g. WordPress).

Cheers,
Christoph

On Wed, 2 Jul 2025, Kamil Tekiela wrote:

On Wed, Jul 2, 2025, 21:58 Gina P. Banyard <internals@gpb.moe> wrote:

> Some should be non-controversial, others a bit more. If such, they
> might warrant their own dedicated RFC, or be dropped from the
> proposal altogether.

ext/filter deprecations

As much as I hate this extension, I don't think deprecating these
functions is the right choice. It's not unheard of for someone to use
filter_input without the filter parameter to avoid getting the warning
on missing value. See the top comment on
PHP: filter_input - Manual

Maybe we should just unbundle that whole extension?

Certainly not. It has been the recommended way of accepting incoming
request variables since whenever we removed magic quotes.

cheers,
Derick

--
https://derickrethans.nl | https://xdebug.org | https://dram.io

Author of Xdebug. Like it? Consider supporting me: Xdebug: Support

mastodon: @derickr@phpc.social @xdebug@phpc.social

On Thu, 3 Jul 2025, Jakub Zelenka wrote:

On Wed, Jul 2, 2025 at 10:00 PM Gina P. Banyard <internals@gpb.moe> wrote:

> It is this time of year again where we proposed a list of
> deprecations to add in PHP 8.5:
>
> PHP: rfc:deprecations_php_8_5

Here are few notes on the ones that I don't agree with:

> Deprecate backticks as an alias for shell_exec

I think this might be too big BC break that might impact many scripts
- would be good to see also if it impacts OSS projects. I guess it
will impact even more non public code bases.

Indeed, I use this *all the time* in quick hacky shell scripts in PHP.
Best practise? Definitely not. But it certainly is very useful.

> Deprecate the error_prepend_string and error_append_string INI
> directives

I think it doesn't have a good enough reason to be deprecated and
might be still used. I don't see any problem with keeping them.

+1

cheers,
Derick

On Fri, 4 Jul 2025, Tim Düsterhus wrote:

On 7/3/25 18:04, Derick Rethans wrote:

> The intention behind the filter extension was that admins can set a
> default filter for *all* data coming in through this
> `filter.default` setting as a "safe" fallback. That could/should
> probably even be a

Genuine question: Is that *intention* documented anywhere?
PHP: filter_input - Manual only makes
factual statements about the behavior, but not how one is supposed to
use them. Similarly
PHP: Runtime Configuration - Manual also says that
a default filter can be configured, but not why one would want to do
so.

I've done a bit of archeology, and came up with the following:

The SAPI API was designed in 2003:

The extension started in PECL in 2005, and then was moved into the core
distribution: PECL :: Package :: filter — unfortunately it
seems that the history of the SVN repository was lost.

There is some context in the mailing list archive:
- ext/filter, Final API proposal - Externals
- Making ext/filter always-on - Externals
- php.internals: ext/filter, add input_get_args, support of scalar or array result
- php.internals: filter, state of the beast, take over

There is a comment from Rasmus on why filter keeps the raw information
in 2006: php.pecl.dev: Re: [PECL-DEV] Input Filter - why not overwrite $_GET, $_POST...?
in 2014: php.internals: Re: Globals, closures, and filter_input

cheers,
Derick

--
https://derickrethans.nl | https://xdebug.org | https://dram.io

Author of Xdebug. Like it? Consider supporting me: Xdebug: Support

mastodon: @derickr@phpc.social @xdebug@phpc.social

Hi

Am 2025-07-10 15:00, schrieb Christoph M. Becker:

Each PHP version is supported for 4 years by the PHP project [1], thus
giving folks at least 4 years to handle each deprecation until they are
forced to upgrade to a supported PHP version.

That point is moot for a lot of software where the developers are not
necessarily in control of which PHP version is used (e.g. WordPress).

In practice this kind of software already needs to check the PHP version and newer PHP versions need to be allow-listed, since newer PHP versions might introduce breaking changes that do not go through the deprecation process (some of them might not even be considered a breaking change, e.g. the introduction of a new class or function). This kind of breaking change would provide even less of a “heads up” compared to a Deprecation. One of those that affected myself was PHP: rfc:static_variable_inheritance.

Best regards
Tim Düsterhus

On Mon, Jul 14, 2025, at 5:36 AM, Derick Rethans wrote:

On Thu, 3 Jul 2025, Jakub Zelenka wrote:

On Wed, Jul 2, 2025 at 10:00 PM Gina P. Banyard <internals@gpb.moe> wrote:

> It is this time of year again where we proposed a list of
> deprecations to add in PHP 8.5:
>
> PHP: rfc:deprecations_php_8_5

Here are few notes on the ones that I don't agree with:

> Deprecate backticks as an alias for shell_exec

I think this might be too big BC break that might impact many scripts
- would be good to see also if it impacts OSS projects. I guess it
will impact even more non public code bases.

Indeed, I use this *all the time* in quick hacky shell scripts in PHP.
Best practise? Definitely not. But it certainly is very useful.

Is their use for quick hacky scripts worth the cost of reserving a symbol that could be repurposed for something else more generally useful in the future? (Not immediately of course, but eventually.)

--Larry Garfield

Deprecate the __sleep() and __wakeup() magic methods

I’m not sure about this one. I don’t think it’s worth it. It’s just an unnecessary BC break IMHO. I would also consider more ext/standard thing rather than language.

I agree with Jakub here, __sleep and __wakeup are just fine. Yes, __serialize/__unserialize are better, but breaking (or even planning to break) existing apps doesn’t look worth the change.

Deprecate the $http_response_header predefined variable

I think it’s too early for this. I would prefer to not deprecate it at this time because alternative is available only from 8.4…

I agree also here: having the alternative available in 8.4 is too soon, especially since the new function cannot be polyfilled.

No strong feelings about the other proposals, I’ll read other’s comments in the thread before voting.

Nicolas

On 2025-07-03 20:34, Morgan wrote:

On 2025-07-03 07:56, Gina P. Banyard wrote:

> Deprecate using values of type null and bool as array offsets and when calling array_key_exists()

Still curious about this. What have you got against

$branch = [false => $fail, true => $pass];

or

$taken = $branch[$test == $match];

?

Hi,

Sorry for having forgotten to answer to this point. To be clearer, I think it is fine for settype() to keep support for the legacy names (“integer”, “boolean”, etc.) returned by gettype(), even if we deprecate the syntax (integer) $x, etc. The syntax (integer) is trivial to correct with a simple search-and-replace; such a correction is not straightforward for settype($a, $type) as $type is not necessarily a literal string. Moreover, the $type argument in settype() is not confusable with hypothetical user-defined types named, e.g., integer, as user-defined types are forbidden in settype() anyway.

—Claude

···

On Wednesday, 9 July 2025 at 22:26, Claude Pache claude.pache@gmail.com wrote:

Hi,

A possible reason for wanting to use the non-canonical names in settype(), is that those names are returned by gettype(). Fictional example (not intended to be reasonable, only illustrative):

function settype_from(&$a, &b) {
return settype($a, gettype($b));
}

Personally, I have used “integer”, etc. instead of “int”, etc., in settype() in the past, because those were the “canonical” (as I perceived) forms returned by gettype(). I have slowly fallen out of that habit in the years after I began to use scalar type declarations (introduced in PHP 7).

We are well aware of this “issue” and get_debug_type() was introduced in PHP 8 as a replacement for gettype() that returns the canonical names.
The one difference is that objects return the class name rather than “object”.
I can add a deprecation of gettype() to nudge people to use get_debug_type() instead, if you think that’s reasonable.

Best regards,

Gina P. Banyard

On Tue, July 8, 2025 at 06:35 Christoph M. Becker wrote:

On 08.07.2025 at 01:30, Theodore Brown wrote:

I believe Derick was commenting specifically on using separate <?php ?> tags interleaved around
each switch, case, break, and endswitch statement (which there are no plans to deprecate). Based
on the follow-up replies from him and Tim, deprecating semicolon-terminated case statements
would not affect his xdebug.org site templates.

The use case we're talking about would be something like (indented to
avoid issues with Newsreaders):

<?switch ($foo):?>
<?case 1?>
<p>1</p>
<?break?>
<?case 2?>
<p>2</p>
<?break?>
<?endswitch?>

If that code wouldn't trigger a deprecation notice, fine. However, we
had apparently introduced an inconsistency then.

Hi Christoph,

I implemented the deprecation in a branch in order to test this [1].
That code would emit deprecation notices, and should be fixed by adding a colon
after each case statement, just like is required after the opening `switch ($foo)`.

Note that I do not advocate writing such code, but I wouldn't be
surprised if such code exists in the wild, but even more suprised if
such code would be found in a Composer package.

If such code does exist anywhere, I expect it to be extremely rare, given how
many PHP devs seem to be surprised that the alternative case syntax is even possible.
Certainly this deprecation should be _far_ less impactful than the curly brace
array/string access syntax that was successfully deprecated in PHP 7.4.

Sincerely,
Theodore Brown

[1]: Deprecate terminating case statements with a semicolon by theodorejb · Pull Request #19215 · php/php-src · GitHub

Hi

Am 2025-07-02 21:56, schrieb Gina P. Banyard:

PHP: rfc:deprecations_php_8_5

Gina asked me to announce the plan to start the vote for her. Except for the "Deprecate using values null as an array offset and when calling array_key_exists()" proposal (which originally was the "Deprecate using values of type null and bool as array offsets and when calling array_key_exists()" proposal), which no longer includes the deprecation of "bool" values as array offsets and got an updated explanation only some minor typographical changes were made to the RFC since July, 9th. This means the vast majority of the proposals have been unchanged for roughly the last two weeks.

Therefore Gina plans to open the vote(s) on Friday (give or take).

Best regards
Tim Düsterhus

Just leaving a note here that I find it inconceivable that the fast majority of proposed deprecation (again) do NOT have an impact analysis. I’ve spoken up about this before and will continue to do this as it basically means a “blind vote”, where voters can only rely on their own experience to gauge the impact and I expect the majority of voters to predominantly work on code which already follows a lot of best practices, which skews the vote towards deprecation, disregarding the real world impact on less clean codebases. As for the proposed deprecations themselves (aside from the fact that the sheer number of proposed deprecations is quite staggering, but that’s been mentioned before), I’m just leaving some opinion here for voters to chew on: == Deprecate semicolon after case in switch statement == Opinion: Feels like an unnecessary deprecation. Side-note: The deprecation is also already flagged by PHPCS and will be auto-fixable as of PHP_CodeSniffer 3.13.3 (via the PSR2.ControlStructures.SwitchDeclaration sniff). == Deprecate attributes applying to multiple class properties/constants == Opinion: while multi-constant and multi-property declarations are not all that common (as PSR-2 forbids them), they are supported in PHP, so I don’t see why it would be necessary to make them second-class citizens with this deprecation. Next you won’t be able to type multi-constant and multi-property declarations… this feels like a wrong turn. == Deprecate backticks as an alias for shell_exec == Opinion: Feels like an unnecessary deprecation unless another purpose for the backtick operator is already planned, in which case, please mention it. == Deprecate the __sleep() and _wakeup() magic methods == Opinion: I foresee this deprecation being problematic for code which needs to support a wider range of PHP versions than just the latest and greatest. These are often used to block (un)serialization for security reasons. == Deprecate using values null as an array offset and when calling array_key_exists() == Opinion: I fear this will just lead to people blindly adding type casts instead of the code being properly fixed. == Deprecate Reflection*::setAccessible() == Opinion: will probably cause quite a lot of busy-work/code churn, but I also see the point of adding the deprecation notice. == Deprecate ReflectionProperty::getDefaultValue() for properties without default values == Opinion: I expect this will cause busy-work again, for little real world gain. == Deprecate passing spl_autoload_call() to spl_autoload_unregister() == Opinion: I’m willing to bet there is at least one codebase doing this deliberately to remove all autoloading callbacks. Having said, the alternative seems reasonable enough. == Deprecate non-canonical type names for settype() == I seem to remember seeing mention of this deprecation proposal being withdrawn, but it’s still in the RFC ? Opinion: I foresee problems with this deprecation as the gettype() method returns the long values, so it would break any code which uses some combination of settype() and gettype(). == Deprecate FILTER_DEFAULT constant == Opinion: I expect this may have a higher impact than anticipated. I also wonder if the deprecation notice shouldn’t mention/suggest using a proper filter instead ? == Make $filter parameter mandatory for filter*() functions == Opinion: makes sense, but I expect this will yield quite some busy work again. == Deprecate no-op functions from the resource to object conversion == Opinion: makes sense as a follow-up, but will cause yet more busy work to add the @ operator everywhere these functions are used in PHP code supporting a wide range of PHP versions. — The other deprecations either make sense to me or I have no opinion on them. Smile, Juliette

···

On 2-7-2025 21:56, Gina P. Banyard wrote:

Hello internals,

It is this time of year again where we proposed a list of deprecations to add in PHP 8.5:

[https://wiki.php.net/rfc/deprecations_php_8_5](https://wiki.php.net/rfc/deprecations_php_8_5)

As a reminder, this list has been compiled over the course of the past year by various different people.

And as usual, each deprecation will be voted in isolation.

We still have a bit of time buffer, so if anyone else has any suggestions, they are free to add them to the RFC.

Some should be non-controversial, others a bit more.
If such, they might warrant their own dedicated RFC, or be dropped from the proposal altogether.

Best regards,

Gina P. Banyard