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

Hello internals,

Similar to the mass deprecation RFC, I would like to propose the addition of a few warnings in certain situations:

I am expecting these 4 sub-proposals to be mostly uncontroversial,
other than possibly, the "Using offsets on non-container values in isset()/empty()" one.

As this is intended to land in PHP 8.5 the discussion will last 2 weeks and voting will commence on Monday the 28th of July 2025.

Best regards,

Gina P. Banyard

Hi Gina,

Le lun. 14 juil. 2025 à 18:22, Gina P. Banyard internals@gpb.moe a écrit :

Hello internals,

Similar to the mass deprecation RFC, I would like to propose the addition of a few warnings in certain situations:
https://wiki.php.net/rfc/warnings-php-8-5

I am expecting these 4 sub-proposals to be mostly uncontroversial,
other than possibly, the “Using offsets on non-container values in isset()/empty()” one.

As this is intended to land in PHP 8.5 the discussion will last 2 weeks and voting will commence on Monday the 28th of July 2025.

Why warnings and not deprecations if the plan is to Error on PHP 9?
As you might know, it’s very common to turn warnings into exceptions in userland so this will break apps for sure. Deprecations don’t if properly handled. Please trigger deprecations instead.

About destructuring non-array values, null is a very common case that allows writing nice readable code.
Here is a dummy example:
if ([$a, $b] = $array[$key] ?? null) { // }

Turning this into a warning will have a significant impact for sure. Even a deprecation would just make the language a bit less pleasant to use without any real benefit, unless I missed any other rationale.

The rest makes sense to me, thanks for spotting these cases.

Nicolas

On Mon, Jul 14, 2025, at 18:20, Gina P. Banyard wrote:

Hello internals,

Similar to the mass deprecation RFC, I would like to propose the addition of a few warnings in certain situations:
https://wiki.php.net/rfc/warnings-php-8-5

I am expecting these 4 sub-proposals to be mostly uncontroversial,
other than possibly, the “Using offsets on non-container values in isset()/empty()” one.

As this is intended to land in PHP 8.5 the discussion will last 2 weeks and voting will commence on Monday the 28th of July 2025.

Best regards,

Gina P. Banyard

Hi Gina, I feel like destructuring null should not be the same warning as other types since null auto-vivicates? to (an empty array). Instead, it should provide the same warning as https://3v4l.org/8QPiD.

— Rob

On Mon, 14 Jul 2025, Gina P. Banyard wrote:

Similar to the mass deprecation RFC, I would like to propose the
addition of a few warnings in certain situations:
PHP: rfc:warnings-php-8-5

I am expecting these 4 sub-proposals to be mostly uncontroversial,
other than possibly, the "Using offsets on non-container values in
isset()/empty()" one.

That one seems to miss examples in the RFC as well. It might be useful
to add those.

Having said that, I am unsure as why I would want to see a way how
isset/empty behave in either the "using offsets on non-container values"
or "using invalid offset types" cases. These language constructs are
often used as a guard in (albeit likely older *code*), and hence, this
now throwing a warning doesn't really add anything for the developer.

I'm also curious to know whether you or somebody else has checked what
the effect of this change on existing code bases would be?

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 Tuesday, 15 July 2025 at 18:16, Nicolas Grekas <nicolas.grekas+php@gmail.com> wrote:

Hi Gina,

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

Hello internals,

Similar to the mass deprecation RFC, I would like to propose the addition of a few warnings in certain situations:
PHP: rfc:warnings-php-8-5

I am expecting these 4 sub-proposals to be mostly uncontroversial,
other than possibly, the "Using offsets on non-container values in isset()/empty()" one.

As this is intended to land in PHP 8.5 the discussion will last 2 weeks and voting will commence on Monday the 28th of July 2025.

Why warnings and not deprecations if the plan is to Error on PHP 9?
As you might know, it's very common to turn warnings into exceptions in userland so this will break apps for sure. Deprecations don't if properly handled. Please trigger deprecations instead.

Because those point to bugs, rather than usage of a valid feature.
As such a warning is appropriate, and people being made aware more quickly about it by an error handler that promotes warnings is the behaviour I want.

About destructuring non-array values, null is a very common case that allows writing nice readable code.
Here is a dummy example:
if ([$a, $b] = $array[$key] ?? null) { /*...*/ }

Turning this into a warning will have a significant impact for sure. Even a deprecation would just make the language a bit less pleasant to use without any real benefit, unless I missed any other rationale.

If you want to provide default values, then surely:

if ([$a, $b] = $array[$key] ?? [null, null])

makes more sense, especially as this allows you to choice different defaults for $a and $b.

Best regards,
Gina P. Banyard

On Tuesday, 15 July 2025 at 20:42, Rob Landers <rob@bottled.codes> wrote:

Hi Gina, I feel like destructuring `null` should not be the same warning as other types since null auto-vivicates? to (an empty array). Instead, it should provide the same warning as Online PHP editor | output for 8QPiD.

Autovivification is only about write operations, not read.
Therefore, I don't really understand that argument because destructuring is a read operation, and reading an offset on null emits:

Trying to access array offset on null

(see Online PHP editor | output for sMkCD)
Which is the same wording as the warning when reading an offset on a scalar:

Warning: Trying to access array offset on int

As such, they should have the same warning here as well.

Best regards,
Gina P. Banyard

Le ven. 18 juil. 2025 à 14:54, Gina P. Banyard internals@gpb.moe a écrit :

On Tuesday, 15 July 2025 at 18:16, Nicolas Grekas <nicolas.grekas+php@gmail.com> wrote:

Hi Gina,

Le lun. 14 juil. 2025 à 18:22, Gina P. Banyard internals@gpb.moe a écrit :

Hello internals,

Similar to the mass deprecation RFC, I would like to propose the addition of a few warnings in certain situations:
https://wiki.php.net/rfc/warnings-php-8-5

I am expecting these 4 sub-proposals to be mostly uncontroversial,
other than possibly, the “Using offsets on non-container values in isset()/empty()” one.

As this is intended to land in PHP 8.5 the discussion will last 2 weeks and voting will commence on Monday the 28th of July 2025.

Why warnings and not deprecations if the plan is to Error on PHP 9?
As you might know, it’s very common to turn warnings into exceptions in userland so this will break apps for sure. Deprecations don’t if properly handled. Please trigger deprecations instead.

Because those point to bugs, rather than usage of a valid feature.
As such a warning is appropriate, and people being made aware more quickly about it by an error handler that promotes warnings is the behaviour I want.

Then obviously this argument doesn’t apply to destructuring non-array values.
This makes me doubtful about the others. A deprecation would be more appropriate to me.

About destructuring non-array values, null is a very common case that allows writing nice readable code.
Here is a dummy example:
if ([$a, $b] = $array[$key] ?? null) { // }

Turning this into a warning will have a significant impact for sure. Even a deprecation would just make the language a bit less pleasant to use without any real benefit, unless I missed any other rationale.

If you want to provide default values, then surely:

if ([$a, $b] = $array[$key] ?? [null, null])

makes more sense, especially as this allows you to choice different defaults for $a and $b.

That’s broken, the “if” will always be truthy using this style.
There’s nothing wrong with the current code. It doesn’t need to be deprecated.
I’d say the same when false is returned BTW.
For other values, I’m not aware of any use cases so might be fine deprecating.

Nicolas

Hi

Am 2025-07-23 13:30, schrieb Nicolas Grekas:

About destructuring non-array values, null is a very common case that
allows writing nice readable code.
Here is a dummy example:
if ([$a, $b] = $array[$key] ?? null) { /*...*/ }

Turning this into a warning will have a significant impact for sure. Even
a deprecation would just make the language a bit less pleasant to use
without any real benefit, unless I missed any other rationale.

If you want to provide default values, then surely:

if ([$a, $b] = $array[$key] ?? [null, null])

makes more sense, especially as this allows you to choice different
defaults for $a and $b.

That's broken, the "if" will always be truthy using this style.
There's nothing wrong with the current code. It doesn't need to be
deprecated.

It seems appropriate to mention the previous (declined) “Destructuring Coalesce” RFC at this point: PHP: rfc:destructuring_coalesce. Perhaps it might make sense to revisit that one?

Best regards
Tim Düsterhus

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

Similar to the mass deprecation RFC, I would like to propose the addition of a few warnings in certain situations:
PHP: rfc:warnings-php-8-5

I am expecting these 4 sub-proposals to be mostly uncontroversial,
other than possibly, the "Using offsets on non-container values in isset()/empty()" one.

As this is intended to land in PHP 8.5 the discussion will last 2 weeks and voting will commence on Monday the 28th of July 2025.

Best regards,

Gina P. Banyard

Hi,

About “ coercing NAN to other types”:

* The result of `(string) NAN` seems reasonable to me and don’t need warning.
* I agree that `(int) NAN` does not make much sense, but if we warn on that, we should also warn on `(int) INF`, which makes even less sense (I expected `(int) INF` to yield `PHP_INT_MAX`, but it yields `0`).
* I strongly think that this should be a deprecation, not a warning. There may be correct programs that rely on the fact that explicit coercing from a random scalar to another scalar type is infallible (as it is the case today), although not expecting a specific value from a buggy input (GIGO principle).

—Claude

On Saturday, 26 July 2025 at 15:16, Claude Pache <claude.pache@gmail.com> wrote:

> Le 14 juil. 2025 à 18:23, Gina P. Banyard internals@gpb.moe a écrit :
> Hello internals,
>
> Similar to the mass deprecation RFC, I would like to propose the addition of a few warnings in certain situations:
> PHP: rfc:warnings-php-8-5

* The result of `(string) NAN` seems reasonable to me and don’t need warning.
* I agree that `(int) NAN` does not make much sense, but if we warn on that, we should also warn on `(int) INF`, which makes even less sense (I expected `(int) INF` to yield `PHP_INT_MAX`, but it yields `0`).

I've added a whole new section that addresses this, as out of range casts are completely whack.
See: PHP: rfc:warnings-php-8-5

Best regards,

Gina P. Banyard

On Wednesday, 23 July 2025 at 14:03, Tim Düsterhus <tim@bastelstu.be> wrote:

Hi

Am 2025-07-23 13:30, schrieb Nicolas Grekas:

> > About destructuring non-array values, null is a very common case that
> > allows writing nice readable code.
> > Here is a dummy example:
> > if ([$a, $b] = $array[$key] ?? null) { /.../ }
> >
> > Turning this into a warning will have a significant impact for sure.
> > Even
> > a deprecation would just make the language a bit less pleasant to use
> > without any real benefit, unless I missed any other rationale.
> >
> > If you want to provide default values, then surely:
> >
> > if ([$a, $b] = $array[$key] ?? [null, null])
> >
> > makes more sense, especially as this allows you to choice different
> > defaults for $a and $b.
>
> That's broken, the "if" will always be truthy using this style.
> There's nothing wrong with the current code. It doesn't need to be
> deprecated.

It seems appropriate to mention the previous (declined) “Destructuring
Coalesce” RFC at this point:
PHP: rfc:destructuring_coalesce. Perhaps it might make
sense to revisit that one?

Best regards
Tim Düsterhus

I've dropped warning null from the proposal, and mentioned the declined RFC.

Best regards,

Gina P. Banyard

On Monday, 14 July 2025 at 17:20, Gina P. Banyard <internals@gpb.moe> wrote:

Hello internals,

Similar to the mass deprecation RFC, I would like to propose the addition of a few warnings in certain situations:
PHP: rfc:warnings-php-8-5

I am expecting these 4 sub-proposals to be mostly uncontroversial,
other than possibly, the "Using offsets on non-container values in isset()/empty()" one.

As this is intended to land in PHP 8.5 the discussion will last 2 weeks and voting will commence on Monday the 28th of July 2025.

As Claude pointed out a major pitfall, that I wasn't even aware of, I added a new proposal to the RFC:
"Casting out of range floats to int"

As I am aware it is in bad taste to shove something new into such a proposal minutes before starting the vote,
I'll postpone the vote for a few hours so that at least _some_ people can see and raise objections.

Best regards,

Gina P. Banyard

Hi

Am 2025-07-28 16:20, schrieb Gina P. Banyard:

I've added a whole new section that addresses this, as out of range casts are completely whack.
See: PHP: rfc:warnings-php-8-5

This effectively is another “Primary Vote” for an entirely new proposal and as such requires 2 weeks of discussion. If you want to vote on this RFC for PHP 8.5, you'll need to drop that section again.

Best regards
Tim Düsterhus

Hi

Am 2025-07-28 16:23, schrieb Gina P. Banyard:

As I am aware it is in bad taste to shove something new into such a proposal minutes before starting the vote,
I'll postpone the vote for a few hours so that at least _some_ people can see and raise objections.

For visibility: I object. See sibling email.

Best regards
Tim Düsterhus

On Monday, 28 July 2025 at 16:22, Tim Düsterhus <tim@bastelstu.be> wrote:

Am 2025-07-28 16:23, schrieb Gina P. Banyard:

> As I am aware it is in bad taste to shove something new into such a
> proposal minutes before starting the vote,
> I'll postpone the vote for a few hours so that at least some people
> can see and raise objections.

For visibility: I object. See sibling email.

Said sibling email:

On Monday, 28 July 2025 at 15:31, Tim Düsterhus <tim@bastelstu.be> wrote:

Am 2025-07-28 16:20, schrieb Gina P. Banyard:

> I've added a whole new section that addresses this, as out of range
> casts are completely whack.
> See:
> PHP: rfc:warnings-php-8-5

This effectively is another “Primary Vote” for an entirely new proposal
and as such requires 2 weeks of discussion. If you want to vote on this
RFC for PHP 8.5, you'll need to drop that section again.

Best regards
Tim Düsterhus

I am going to bring the RFC in its totality to a vote later today.
You can consider this a new primary vote, vote no, and even argue for this part of the RFC to be rendered void regardless of the result.
Or just incentivize people to vote no, so you don't even need to deal with this.

Claude raised the edge case 2 days ago, and I found the extent of it to be even larger than expected.
I thought that it would be better to create a whole new section rather than twisting the existing "NAN" warning proposal to fit the new constraints,
but apparently I should have done this instead and changed all instances of "NAN" to "non-representable floats".

I find it increasingly frustrating that trying to make PHP not be completely insane is met with resistance at every turn,
and I'm once more at the stage that I really should stop wasting my time and caring about PHP and do something better with my life.
Using "process violations" to prevent PHP from being less shit when an additional edge case of a proposal is found, for IDK 5 additional years impacting countless developers, old and new, is something that I find infuriating.
And I guess this truly showcases how broken and infuriating our RFC process can be, especially around feature freeze.

Moreover, if we are going to do legalese, the only thing our policy actual states are the following: [1]

There'd be a minimum of 2 weeks between when an RFC that touches the language is brought up on this list and when it's voted on is required. [...]

For procedural reasons, multiple RFCs may be combined into one, in which case there may be multiple primary votes.
Combining multiple RFCs into one does not allow turning a primary vote into a secondary vote.

There is no mention of the content of an RFC needing to be "identical" for 2 weeks.
Thus, I can, and seemingly I really should have, edited the "NAN" proposal (or any of the other ones) to include this and then make it a secondary vote "should this be extended to non-representable floats or not".
Therefore, if there is even more push back, I will proceed that way, so the grouping only has 4 "main proposals" rather than 5.

Sincerely,

Gina P. Banyard

[1] policies/feature-proposals.rst at main · php/policies · GitHub

Hi Gina

On Mon, Jul 28, 2025 at 7:15 PM Gina P. Banyard <internals@gpb.moe> wrote:

I find it increasingly frustrating that trying to make PHP not be completely insane is met with resistance at every turn,
and I'm once more at the stage that I really should stop wasting my time and caring about PHP and do something better with my life.

I appreciate all the work you have put into PHP. However, I don't
think threatening to quit PHP over disagreements (which is not the
first time either, I believe) creates a healthy environment for
discussion. Internals should not fear voicing their concerns. I also
believe the concern is not technical, and this would have no trouble
passing in the next version.

Ilija

On Monday, 28 July 2025 at 19:08, Ilija Tovilo <tovilo.ilija@gmail.com> wrote:

Hi Gina

On Mon, Jul 28, 2025 at 7:15 PM Gina P. Banyard internals@gpb.moe wrote:

> I find it increasingly frustrating that trying to make PHP not be completely insane is met with resistance at every turn,
> and I'm once more at the stage that I really should stop wasting my time and caring about PHP and do something better with my life.

I appreciate all the work you have put into PHP. However, I don't
think threatening to quit PHP over disagreements (which is not the
first time either, I believe) creates a healthy environment for
discussion. Internals should not fear voicing their concerns. I also
believe the concern is not technical, and this would have no trouble
passing in the next version.

Ilija

Hi Ilija,

Let's take a breath and review what's going on.

My original proposal was to warn when type juggling NAN, as this is unexpected
behaviour, and this was discussed on the mailing list. Then, just this
Saturday, Claude pointed out that INF also has this problem (casting INF to int
produces zero, which is even more clearly a problem). After confirming this
and thinking about it, I wanted to modify my existing wording to account for
this edge case; doing so would have resulted in very convoluted language,
however, so instead I added the new proposal to make it clear this is a closely
related but even more narrow change.

This is the highest possible bar that I have set: adding the new edge case as a
secondary vote would have been completely justified, and this would require a
smaller majority of a vote. If I was worried about a procedural spanner in the
works, I could have just shoehorned this minor change into the existing text
and this would also have been completely justified. I made the changes in the
clearest possible way for the benefit of people reading the wiki.

I will now open the vote as-is, anyone is free to convince people to simply
vote against it, or do the most procedurally correct thing of starting an RFC
to render it void after the fact (regardless of the outcome of this vote).

Regarding the suggestion to simply kick the can down the road to the next
version: we do not know if the next version will be 9.0, which if the same
request is made about deprecation as 8.0 had, this would mean the warning for
this could not be introduced until 9.1, and then it could only be upgraded to
an error by PHP 10.0. This seems like a disproportionate amount of extra work
for such a minor change.

I agree it is important for internals to voice their concerns. I am simply
upset that a very minor *procedural* disagreement is once again incentivising
me to smuggle in common-sense changes through procedural back doors rather than
write my proposals clearly. This seems like a clearly positive and minor
change; anyone who disagrees on *technical* grounds can vote no, and if the
procedural issue really is so important, there is a recourse available for
this. Having to fight these kinds of battles over my work to improve the
language is needlessly taxing, and this too is a form of unhealthy environment.

Best regards,

Gina P. Banyard

On Tue, Jul 29, 2025, at 11:01, Gina P. Banyard wrote:

On Monday, 28 July 2025 at 19:08, Ilija Tovilo <tovilo.ilija@gmail.com> wrote:

Hi Gina

On Mon, Jul 28, 2025 at 7:15 PM Gina P. Banyard internals@gpb.moe wrote:

I find it increasingly frustrating that trying to make PHP not be completely insane is met with resistance at every turn,
and I’m once more at the stage that I really should stop wasting my time and caring about PHP and do something better with my life.

I appreciate all the work you have put into PHP. However, I don’t
think threatening to quit PHP over disagreements (which is not the
first time either, I believe) creates a healthy environment for
discussion. Internals should not fear voicing their concerns. I also
believe the concern is not technical, and this would have no trouble
passing in the next version.

Ilija

Hi Ilija,

Let’s take a breath and review what’s going on.

My original proposal was to warn when type juggling NAN, as this is unexpected
behaviour, and this was discussed on the mailing list. Then, just this
Saturday, Claude pointed out that INF also has this problem (casting INF to int
produces zero, which is even more clearly a problem). After confirming this
and thinking about it, I wanted to modify my existing wording to account for
this edge case; doing so would have resulted in very convoluted language,
however, so instead I added the new proposal to make it clear this is a closely
related but even more narrow change.

This is the highest possible bar that I have set: adding the new edge case as a
secondary vote would have been completely justified, and this would require a
smaller majority of a vote. If I was worried about a procedural spanner in the
works, I could have just shoehorned this minor change into the existing text
and this would also have been completely justified. I made the changes in the
clearest possible way for the benefit of people reading the wiki.

I will now open the vote as-is, anyone is free to convince people to simply
vote against it, or do the most procedurally correct thing of starting an RFC
to render it void after the fact (regardless of the outcome of this vote).

Regarding the suggestion to simply kick the can down the road to the next
version: we do not know if the next version will be 9.0, which if the same
request is made about deprecation as 8.0 had, this would mean the warning for
this could not be introduced until 9.1, and then it could only be upgraded to
an error by PHP 10.0. This seems like a disproportionate amount of extra work
for such a minor change.

I agree it is important for internals to voice their concerns. I am simply
upset that a very minor procedural disagreement is once again incentivising
me to smuggle in common-sense changes through procedural back doors rather than
write my proposals clearly. This seems like a clearly positive and minor
change; anyone who disagrees on technical grounds can vote no, and if the
procedural issue really is so important, there is a recourse available for
this. Having to fight these kinds of battles over my work to improve the
language is needlessly taxing, and this too is a form of unhealthy environment.

Best regards,

Gina P. Banyard

I am not sure that (int)“INF” or (int)“NAN” is misbehaving. (int)“Password” also produces 0, and these are strings. If we had the time to discuss it properly, I would argue that simply warning when casting a string to int is the most sensible thing, just like we get an error when coercing a string to int, which is more consistent across the language than just special casing some strings.

— Rob

On Tue, Jul 29, 2025 at 12:18 PM Rob Landers rob@bottled.codes wrote:

I am not sure that (int)“INF” or (int)“NAN” is misbehaving. (int)“Password” also produces 0, and these are strings. If we had the time to discuss it properly, I would argue that simply warning when casting a string to int is the most sensible thing, just like we get an error when coercing a string to int, which is more consistent across the language than just special casing some strings.

This is about INF and NAN, the float values, not the strings “INF” and “NAN”.
https://3v4l.org/fAFn3

– Alex

On Tue, Jul 29, 2025, at 13:16, Alexandru Pătrănescu wrote:

On Tue, Jul 29, 2025 at 12:18 PM Rob Landers rob@bottled.codes wrote:

I am not sure that (int)“INF” or (int)“NAN” is misbehaving. (int)“Password” also produces 0, and these are strings. If we had the time to discuss it properly, I would argue that simply warning when casting a string to int is the most sensible thing, just like we get an error when coercing a string to int, which is more consistent across the language than just special casing some strings.

This is about INF and NAN, the float values, not the strings “INF” and “NAN”.
https://3v4l.org/fAFn3

– Alex

Thanks Alex, I missed that nuance!

— Rob