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

Hi

On 7/3/25 16:45, Ilija Tovilo wrote:

Deprecate passing spl_autoload_call() to spl_autoload_unregister()

Is such a check actually useful? We can prevent
spl_autoload_unregister(spl_autoload_call(...)), but we can't prevent
spl_autoload_unregister(fn($c) => spl_autoload_call($c)). It seems
very unlikely for this to happen accidentally, and excluding all
functions that don't make sense to pass is not feasible for obvious
reasons. But I don't care too much.

See also my reply to Niels. Such a check already exists:

That's an explicit special case in the language that could go away.

Best regards
Tim Düsterhus

Hey,

Good idea. I can support that. That one is probably just getting rid of the special casing in the code, which I’d support.

···

On 4.7.2025 09:01:52, Niels Dossche wrote:

Hi

First of all, that's a huge list of deprecations and I think we should tone down on that.
Especially if a feature still has a purpose and is not harmful or buggy, then we should probably consider not deprecating it.

Yeah, I agree. The list of deprecations is too big and possibly should be multiple RFCs. Let’s keep it in mind for next year at least, please.

Deprecating should be a selective process, just like adding features is. I don’t think we really have big RFCs which simply add a bunch of unrelated stuff.

Secondly, I'm tired of having to deal with useless deprecation messages.
A lot of deprecation messages are completely useless for developers because they do not point to a reason or a replacement.
That leaves you needing to look up the documentation, which is also incomplete.
See [https://github.com/php/php-src/issues/14320](https://github.com/php/php-src/issues/14320)
Therefore, any deprecation proposed in this RFC that does not explicitly list the deprecation message, I will vote no for.
There are some things in the list I don't care about or I don't have a lot of insight of its uses in, and I will abstain for voting on them.

There are a few things I will vote no for:

* Deprecate semicolon after case in switch statement.
  People seem to use this and it doesn't seem harmful to have. Just because you don't like it doesn't mean we should yeet it.

* Deprecate attributes applying to multiple class properties/constants.
  On the edge, confusing yes, but it might break real code.

* Deprecate using values of type null and bool as array offsets and when calling array_key_exists()
  Deprecating this would make the language more inconsistent by allowing this on array offsets but not on the function.

* Deprecate __debugInfo() returning null
  Weird, especially as the docs say the return type is ": array", but not harmful.

* Deprecate ReflectionParameter::allowsNull()
  This shorthand doesn't hurt anybody, and is convenient, I don't see the point in deprecating it.

* Deprecate passing spl_autoload_call() to spl_autoload_unregister()
  This is very ad hoc, and as Ilija pointed out, we can't prevent workarounds for this. So what's the point really.
  The behaviour may be weird, but notice that people won't do this by accident.
* Deprecate passing null to readdir(), rewinddir(), and closedir()
  Dubious but not really harmful I think.

* Based on Derick's comments I will vote no on the ext/filter deprecations. I was already going to vote no on the filter_* functions though.

* Deprecate driver specific PDO constants and methods
  Too early.

Kind regards
Niels

To add to Niels list:

  • Deprecate passing string which are not one byte long to ord()
    This behaviour is consistent with mb_ord() as well. If we deprecate one, we also should deprecate the other. But that makes no sense, because the latter is not fixed with. So let’s just not deprecate either.

  • Some INI deprecations:

** Deprecate the docref_root and docref_ext INI directives
What’s the point? Why do these need to be deprecated? If these are not set you do not get clickable links at all, unrelated to mirrors and such.

** Deprecate the error_prepend_string and error_append_string INI directives
Why is that of questionable use? Why is “this is a development and debugging feature” considered a valid reason to get rid of something? It allows prominently displaying issues in development when they would be hidden behind other HTML otherwise.

** Deprecate the report_memleaks INI directive
So, “I’m currently working with this code having a known memory leak and I want to suppress it” is not a valid reason? If you select that that’s a very deliberate opt-in.

Bob

Hey Tim,

On 6.7.2025 15:35:16, Tim Düsterhus wrote:

Hi

Since this is a recurring thing, I feel compelled to point out terminology: A deprecation in itself is not a breaking change.

Let me disagree with this. Yes, a deprecation in *itself* doesn't break running code. However it is both a) an annoyance (you want to get rid of deprecations) and b) a promise that it will be eventually broken.

So, it requires a code change, maybe not immediately, but it will. And that's what we're getting at. It will break real code, just not right now.

And there's not always a point in breaking real code for the sake of "this might be potentially confusing".

(And for the feature in question, I do disagree that it's confusing, but that's not the point of this mail.)

Bob

Hi

On 7/6/25 19:00, Bob Weinand wrote:

Let me disagree with this. Yes, a deprecation in *itself* doesn't break
running code. However it is both a) an annoyance (you want to get rid of
deprecations) and b) a promise that it will be eventually broken.

Yes, I understand that a deprecation *usually* leads to a removal.

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.

From my personal anecdata: I'm fixing deprecations right away and the only painful one I'm remembering in the recent years is PHP: rfc:deprecate_null_to_scalar_internal_arg. For this iteration, I'm likewise expecting most of them to be easily handled with the existing tooling (IDEs, Code formatters, …).

Also, even for PHP 8.4, where the proposed deprecation of `uniqid()` (and others) specifically said that there are *no plans for removal* (PHP: rfc:deprecations_php_8_4), folks considered the deprecation warning alone to be an inacceptable breaking change.

And there's not always a point in breaking real code for the sake of
"this might be potentially confusing".

Yes, the amount of possible confusion certainly needs to be weighted against the amount of usage. As a rule of thumb, I'd claim that the more commonly a specific syntax is used, the less confusing it becomes, since there are more references in the wild for folks to come across.

Best regards
Tim Düsterhus

On Thursday, 3 July 2025 at 15:49, Ilija Tovilo <tovilo.ilija@gmail.com> wrote:

Hi everyone

On Wed, Jul 2, 2025 at 9:58 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

Thanks for the bulk RFC. Some thoughts.

> Deprecate __construct() and __destruct() in interfaces

We agreed with Tim to remove it from this RFC.
We still think __destruct() in interfaces should be deprecated,
but there are other interactions with __destruct() that should be on the chopping board,
so this is punted to later with a comprehensive proposal.

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

The introduction section also lists float as a type to be deprecated
in array offsets:

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

Floats used as array offsets that lose precision already emit a
warning. Can you confirm that floats used as array offsets that do not
lose precision will not start emitting a deprecation?

Correct, that was a left over from a previous iteration.
This should be fixed now.

> Deprecate ArrayObject and ArrayIterator with objects

Just to add another issue to the list: It can also change readonly
properties of internal classes that the engine does not expect to ever
change. For example, Enum::$name and Enum::$value. This can break
internal logic assumptions (e.g. hard-coded switch cases to handle
internal enums by name) and cause memory corruption. The same goes for
non-readonly properties guarded with the internal equivalent of
__set().

Added this as an example

> Deprecate passing spl_autoload_call() to spl_autoload_unregister()

Is such a check actually useful? We can prevent
spl_autoload_unregister(spl_autoload_call(...)), but we can't prevent
spl_autoload_unregister(fn($c) => spl_autoload_call($c)). It seems

very unlikely for this to happen accidentally, and excluding all
functions that don't make sense to pass is not feasible for obvious
reasons. But I don't care too much.

As Tim mentioned, this is not about preventing workarounds but removing the ability to "flush" the autoloading table.
See Online PHP editor | output for GVl7Z which showcases that a "proxy" call to spl_autoload_call() does NOT behave the same as passing it directly to the function.

Best regards,

Gina P. Banyard

On Wednesday, 2 July 2025 at 21:47, Larry Garfield <larry@garfieldtech.com> wrote:

For the DB-specific PDO constants, am I correct that all of those constants and methods already have equivalents in their respective driver classes? (If so, please state that explicitly.)

I have added the corresponding constant/method.

Best regards,

Gina P. Banyard

On Wednesday, 2 July 2025 at 21:57, Calvin Buckley <calvin@cmpct.info> wrote:

On Jul 2, 2025, at 4:56 PM, Gina P. Banyard internals@gpb.moe wrote:

> Hello internals,
>
> 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
>
> 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

Thanks for reminding me I should dust off my proposal for cleaning up
ODBC driver support. Might be a good idea to put it to a vote...

Look into supported driver managers for ODBC extension and how we handle them · Issue #15630 · php/php-src · GitHub

Feel free to write a blurb to explain the rationale and add it to the RFC! :slight_smile:

Best regards,

Gina P. Banyard

On Jul 7, 2025, at 12:22 PM, Gina P. Banyard <internals@gpb.moe> wrote:

On Wednesday, 2 July 2025 at 21:57, Calvin Buckley <calvin@cmpct.info> wrote:

Thanks for reminding me I should dust off my proposal for cleaning up
ODBC driver support. Might be a good idea to put it to a vote...

Look into supported driver managers for ODBC extension and how we handle them · Issue #15630 · php/php-src · GitHub

Feel free to write a blurb to explain the rationale and add it to the RFC! :slight_smile:

Best regards,

Gina P. Banyard

Sure, I'll add it!

On Thursday, 3 July 2025 at 17:05, Derick Rethans <derick@php.net> wrote:

On Wed, 2 Jul 2025, Gina P. Banyard 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.

The changes to filter continue to undermine what the extension was meant
to do. The filter.default INI setting was deprecated in PHP
8.1, which was already a mistake.

The reason that INI setting was deprecated was because it was effectively resurrecting magic quotes, and even weirder combinations.
So no, it was deprecated for a good reason, but if you care so much about this, feel free to raise an RFC to undeprecate it.

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
filter that just makes all data ":smiling_face:" for example, to indicate you're
working with unsanitised data. (I don't think there is such a filter
though).

This fallback could then be 'circumvented' by using the
filter_input/input_array() functions, so that each of them can employ
its own unique, and useful, filter on that specific element in the
GET/POST/etc arrays.

Saying that "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. " is
basically documenting the original intention of these functions.

In such case, we should provide sapi_X() functions that allow to query the raw values even without the filter extension.
Regardless, I have removed the functions from the RFC as multiple people find use in them.

If there is anything odd with your example, is that you can modify the
values in GET/POST/etc superglobals to begin with.

This is core PHP behaviour, if you want to propose making those values read only, I would be in favour.

"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()."

No. The whole point is that these functions read the raw data, the one
that wasn't filtered by the default filter (which has been inadvisably
deprecated).

I would therefore undeprecate filter.default, and allow these filter
functions are they currently are, because they implement the original
design idea behind this extension.

cheers,
Derick

Again I disagree that the INI setting should be undeprecated as stated above.
Moreover, I would love to know what the original design idea of this extension is and why was this never documented.
Because the documentation was in a horrendous state before I tried improving it last winter, and the extension is also in a state filled with bugs and XFAILed tests.

Best regards,

Gina P. Banyard

On Friday, 4 July 2025 at 22:52, Peter Kokot <petk@php.net> wrote:

I'd also suggest deprecating building ext/readline with the Readline library and
ext/dba with the GDBM library.

These two libraries are released under the GPL-3 license, which is not
compatible with PHP. In practice this means that PHP linked with GPL-3-licensed
software should not be distributed, making it impractical for any server
environment beyond a local testing project. This issue isn't immediately
obvious, but many packagers need to be aware of it and avoid building with these
libraries.

ext/readline works fine with the Editline library as an alternative,
ext/dba works fine with other handlers.

This suggestion would otherwise delay resolving the issue, as it would require
an RFC vote - something I hoped to avoid in pull requests. But I suppose that's
how it has to be handled.

See also:
- GNU Readline should be replaced with libedit · Issue #15882 · php/php-src · GitHub
- The GDBM is GPL 3 licensed and incompatible with PHP license · Issue #16826 · php/php-src · GitHub
- PHP: License Information

Feel free to add a section to the RFC! :slight_smile:
If we are going to deprecate some DBA libraries I would also chuck in some of the old DBA versions that we can't test in CI as they don't seem to be provided anywhere.

Best regards,
Gina P. Banyard

On Friday, 4 July 2025 at 08:04, Niels Dossche <dossche.niels@gmail.com> wrote:

Hi

First of all, that's a huge list of deprecations and I think we should tone down on that.
Especially if a feature still has a purpose and is not harmful or buggy, then we should probably consider not deprecating it.

The list of deprecation being "huge" is a consequence of more people working on php-src.
We previously also had "large" deprecation RFCs like the one for 8.1, with some deprecations dropped.
See: PHP: rfc:deprecations_php_8_1

Moreover, "harmful" is very much in the eyes of the beholder.

Secondly, I'm tired of having to deal with useless deprecation messages.
A lot of deprecation messages are completely useless for developers because they do not point to a reason or a replacement.
That leaves you needing to look up the documentation, which is also incomplete.
See Deprecation messages are often not helpful · Issue #14320 · php/php-src · GitHub
Therefore, any deprecation proposed in this RFC that does not explicitly list the deprecation message, I will vote no for.

I have added the deprecations messages for my own proposals,
but I don't see this as a valid reason to vote against one.
The deprecation message is very much an implementation detail, and we should be able to improve it at any point.
This is also *much* easier now that we can use the #[Deprecated] attributes on the majority of internals symbols, as that was one of the major limitations.

There are some things in the list I don't care about or I don't have a lot of insight of its uses in, and I will abstain for voting on them.

There are a few things I will vote no for:

[...]

* Deprecate using values of type null and bool as array offsets and when calling array_key_exists()
Deprecating this would make the language more inconsistent by allowing this on array offsets but not on the function.

I am slightly confused by what you mean by "allowing this on array offsets but not on the function".
However, null is not accepted by functions that accept scalar types, and bool would neither if my other RFC is approved.
Moreover, a type declaration of int|string accepted Stringable objects, however array offsets do not accept objects at all.

* Deprecate _debugInfo() returning null
Weird, especially as the docs say the return type is ": array", but not harmful.

Again, harmful here is very subjective.
But as this is not my proposal, I will not comment further on it.

[...]

* Deprecate passing spl_autoload_call() to spl_autoload_unregister()
This is very ad hoc, and as Ilija pointed out, we can't prevent workarounds for this. So what's the point really.
The behaviour may be weird, but notice that people won't do this by accident.

As replied to Ilija, and as Tim already mentioned, the workaround do NOT behave the same way as passing the function directly.

* Deprecate passing null to readdir(), rewinddir(), and closedir()
Dubious but not really harmful I think.

I disagree that relying on implicit global state is not harmful.

* Based on Derick's comments I will vote no on the ext/filter deprecations. I was already going to vote no on the filter* functions though.

I have removed the functions anyway, however FILTER_DEFAULT is an incredibly problematic name, and not passing a filter is also problematic, so those remain on the RFC.

* Deprecate driver specific PDO constants and methods
Too early.

I disagree with too early as the migrations for the constants is extremely easy and can be done by tools like Rector (or hell even sed if you feel adventurous)
and the methods are effectively a hack on the PDO class which is already weird enough.

Best regards,

Gina P. Banyard

On Monday, 7 July 2025 at 16:46, Eric Norris <eric.t.norris@gmail.com> wrote:

> ** Deprecate the error_prepend_string and error_append_string INI directives
> Why is that of questionable use? Why is "this is a development and debugging feature" considered a valid reason to get rid of something? It allows prominently displaying issues in development when they would be hidden behind other HTML otherwise.

I recently made a change to the php_error_cb function for the Error
Backtraces v2 RFC (PHP: rfc:error_backtraces_v2), and
I recall that working inside that function was quite difficult. The
error_prepend_string and error_append_string directives are a tiny
part of the complexity there, but nonetheless removing them would
maybe start to move us in a direction of greatly simplifying the
implementation of php_error_cb, which I would support. I don't have
strong feelings here, however.

I removed it as it seems my justification was not enough,
if you still think it would be worthwhile by expanding on this complexity, that would be great!
I do know aswell that any call to zend_error() doesn't use the docref IIRC, which leads to very inconsistent styling.

Best regards,

Gina P. Banyard

** Deprecate the error_prepend_string and error_append_string INI directives
   Why is that of questionable use? Why is "this is a development and debugging feature" considered a valid reason to get rid of something? It allows prominently displaying issues in development when they would be hidden behind other HTML otherwise.

I recently made a change to the php_error_cb function for the Error
Backtraces v2 RFC (PHP: rfc:error_backtraces_v2), and
I recall that working inside that function was quite difficult. The
error_prepend_string and error_append_string directives are a tiny
part of the complexity there, but nonetheless removing them would
maybe start to move us in a direction of greatly simplifying the
implementation of php_error_cb, which I would support. I don't have
strong feelings here, however.

On 07/07/2025 17:48, Gina P. Banyard wrote:

On Friday, 4 July 2025 at 08:04, Niels Dossche <dossche.niels@gmail.com> wrote:

Secondly, I'm tired of having to deal with useless deprecation messages.
A lot of deprecation messages are completely useless for developers because they do not point to a reason or a replacement.
That leaves you needing to look up the documentation, which is also incomplete.
See Deprecation messages are often not helpful · Issue #14320 · php/php-src · GitHub
Therefore, any deprecation proposed in this RFC that does not explicitly list the deprecation message, I will vote no for.

I have added the deprecations messages for my own proposals,

Thanks!

but I don't see this as a valid reason to vote against one.
The deprecation message is very much an implementation detail, and we should be able to improve it at any point.

True, and I have voted against things before due to implementation details.

There are some things in the list I don't care about or I don't have a lot of insight of its uses in, and I will abstain for voting on them.

There are a few things I will vote no for:

[...]

* Deprecate using values of type null and bool as array offsets and when calling array_key_exists()
Deprecating this would make the language more inconsistent by allowing this on array offsets but not on the function.

I am slightly confused by what you mean by "allowing this on array offsets but not on the function".
However, null is not accepted by functions that accept scalar types, and bool would neither if my other RFC is approved.
Moreover, a type declaration of int|string accepted Stringable objects, however array offsets do not accept objects at all.

I'll clarify:
You're allowed to do $array[null], $array[3.14], etc... and the key will coerce.
I expect array_key_exists() to behave the same way as keys on array accesses do.

* Deprecate passing spl_autoload_call() to spl_autoload_unregister()
This is very ad hoc, and as Ilija pointed out, we can't prevent workarounds for this. So what's the point really.
The behaviour may be weird, but notice that people won't do this by accident.

As replied to Ilija, and as Tim already mentioned, the workaround do NOT behave the same way as passing the function directly.

Yeah, I misunderstood this.

Kind regards
Niels

On Fri, July 4, 2025 at 01:01 Niels Dossche wrote:

There are a few things I will vote no for:

* Deprecate semicolon after case in switch statement.
People seem to use this and it doesn't seem harmful to have. Just because you don't like it doesn't mean we should yeet it.

Can you point to a project in current use where this syntax is intentionally used? I searched quite extensively
(even well beyond the top 1000 Composer packages where there are zero usages) and only found a tiny number of
accidental usages (e.g. where all the cases in a switch statement had a normal colon except one which had a semicolon typo).
Almost all of these were quickly fixed by sending a pull request.

Maybe the unnecessary legacy syntax doesn't seem harmful, but I disagree. Non-standard alternate syntax can cause confusion
about a potential behavioral difference, and sometimes can even hold back future features (for example, deprecating the curly
brace array access syntax in PHP 7.4 made it possible to implement property hooks in PHP 8.4).

I updated the RFC to document the planned deprecation message, as well a command which automatically fixes any usages in a project.

Kind regards,
Theodore Brown

On Mon, July 7, 2025 at 11:03 Niels Dossche wrote:

There are a few things I will vote no for:

[...]

* Deprecate using values of type null and bool as array offsets and when calling array_key_exists()
Deprecating this would make the language more inconsistent by allowing this on array offsets but not on the function.

I am slightly confused by what you mean by "allowing this on array offsets but not on the function".
However, null is not accepted by functions that accept scalar types, and bool would neither if my other RFC is approved.
Moreover, a type declaration of int|string accepted Stringable objects, however array offsets do not accept objects at all.

I'll clarify:
You're allowed to do $array[null], $array[3.14], etc... and the key will coerce.
I expect array_key_exists() to behave the same way as keys on array accesses do.

I'm confused what you mean as well. The deprecation is for both array offsets and when calling array_key_exists().
So $array[null] should output a deprecation just like the function, and there isn't any inconsistency.

Regards,
Theodore Brown

On 07/07/2025 21:19, Theodore Brown wrote:

On Mon, July 7, 2025 at 11:03 Niels Dossche wrote:

You're allowed to do $array[null], $array[3.14], etc... and the key will coerce.
I expect array_key_exists() to behave the same way as keys on array accesses do.

I'm confused what you mean as well. The deprecation is for both array offsets and when calling array_key_exists().
So $array[null] should output a deprecation just like the function, and there isn't any inconsistency.

Okay now I understand. I misread the description and missed the word "and".

However, I still need some clarifications:

From the RFC:

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.

Why is this wrong? Why must it get cast to 0?

From the RFC:

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.

I tried understanding this sentence multiple times but I just don't understand what it's saying.
Even presuming that the first "that" should maybe be "than", I still don't understand it.

Kind regards
Niels

On 07/07/2025 20:55, Theodore Brown wrote:

On Fri, July 4, 2025 at 01:01 Niels Dossche wrote:

There are a few things I will vote no for:

* Deprecate semicolon after case in switch statement.
People seem to use this and it doesn't seem harmful to have. Just because you don't like it doesn't mean we should yeet it.

Can you point to a project in current use where this syntax is intentionally used? I searched quite extensively
(even well beyond the top 1000 Composer packages where there are zero usages) and only found a tiny number of
accidental usages (e.g. where all the cases in a switch statement had a normal colon except one which had a semicolon typo).
Almost all of these were quickly fixed by sending a pull request.

See Deprecate alternate switch case syntax? - Externals, in particular Derick's reply.
Also I'm sure there's a lot of brownfield PHP code that we have no idea about how it looks like.

Maybe the unnecessary legacy syntax doesn't seem harmful, but I disagree. Non-standard alternate syntax can cause confusion
about a potential behavioral difference, and sometimes can even hold back future features (for example, deprecating the curly
brace array access syntax in PHP 7.4 made it possible to implement property hooks in PHP 8.4).

Sure, but whether it opens up anything useful in the future is highly speculative.

I updated the RFC to document the planned deprecation message, as well a command which automatically fixes any usages in a project.

:+1:

Kind regards
Niels

Apologies for the duplicate; I missed CCing Internals previously.

On Mon, July 7, 2025 at 13:53 Niels Dossche wrote:

There are a few things I will vote no for:

* Deprecate semicolon after case in switch statement.
  People seem to use this and it doesn't seem harmful to have. Just because you don't like it doesn't mean we should yeet it.

Can you point to a project in current use where this syntax is intentionally used? I searched quite extensively
(even well beyond the top 1000 Composer packages where there are zero usages) and only found a tiny number of
accidental usages (e.g. where all the cases in a switch statement had a normal colon except one which had a semicolon typo).
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.

Also I'm sure there's a lot of brownfield PHP code that we have no idea about how it looks like.

Perhaps, but even if so the migration is automatic with a single php-cs-fixer command.

Maybe the unnecessary legacy syntax doesn't seem harmful, but I disagree. Non-standard alternate syntax can cause confusion
about a potential behavioral difference, and sometimes can even hold back future features (for example, deprecating the curly
brace array access syntax in PHP 7.4 made it possible to implement property hooks in PHP 8.4).

Sure, but whether it opens up anything useful in the future is highly speculative.

I updated the RFC to document the planned deprecation message, as well a command which automatically fixes any usages in a project.

:+1:

Kind regards,
Theodore

Hi,

I'd like to add a bit to the harmful/useful debate.

While writing a `->setAccessible(true)` is not harmful per se, it's a clear indication one is following an outdated example/tutorial. New code should never contain it, not even for consistency (which could be argued for `__sleep()` if your codebase already has a couple of those). I would label a deprecation message for `setAccessible` as useful.

A semicolon for the switch cases, on the other hand, seems more like an easter egg and I'd love for it to stay just so PHP could keep that side of it's personality. I have similar feelings for `5d9` slowly incrementing to `6`. It's funny and unused and an excellent trivia piece. It would be sad to add a "but it no longer works since 8.5" to the stories.

BR,
Juris

-----Original Message-----
From: Gina P. Banyard <internals@gpb.moe>
Sent: Wednesday, July 2, 2025 10:56 PM
To: PHP internals <internals@lists.php.net>
Subject: [PHP-DEV] [RFC] Deprecations for PHP 8.5

Hello internals,

It is this time of year again where we proposed a list of deprecations to add in 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