[PHP-DEV][RFC] Deprecate type juggling to and from bool type within the function type juggling context

Hello internals,

This is the first RFC out of a set of type system related RFCs I want to propose for PHP 8.5.
It also used the recently enabled Markdown support on the wiki, so there might be a few oddities.

The RFC proposes to deprecate implicit type coercions to and from the bool type for other scalar types.
This a "weak" mode change only, as when strict_types are enabled none of these coercions can happen.

Let me know what you think about it.

RFC: PHP: rfc:deprecate-function-bool-type-juggling

Best regards,

Gina P. Banyard

On Mon, Jun 2, 2025, at 18:11, Gina P. Banyard wrote:

Hello internals,

This is the first RFC out of a set of type system related RFCs I want to propose for PHP 8.5.
It also used the recently enabled Markdown support on the wiki, so there might be a few oddities.

The RFC proposes to deprecate implicit type coercions to and from the bool type for other scalar types.
This a “weak” mode change only, as when strict_types are enabled none of these coercions can happen.

Let me know what you think about it.

RFC: https://wiki.php.net/rfc/deprecate-function-bool-type-juggling

Best regards,

Gina P. Banyard

No offense, but this feels like it was written by someone who doesn’t use non-strict mode very often. The rules around coercion are pretty simple and well documented. Further, this makes a ton of shorthand nearly impossible — the manual casting to bool in strict mode is one of the most annoying casts someone has to do (and people screw up order of operations all the time leading to subtle bugs worse than coercion). Bringing this into all of php is probably not a good idea.

Type juggling of strings to bool is similarly error-prone. The strings “” and “0” are converted to false, but “false”, " ", and other strings which an (int) cast converts to 0 are coerced to true.

If I understand correctly, you are saying it is weird why the bytes 66 61 6C 73 65 are “true” and 30 is a special case, but not 20? If I remember my history correctly, 30 is special-cased because forms used to send “0” on checkboxes (if it sent it at all; it changed from decade to decade).

I don’t see the benefit of removing this implicit coercion.

— Rob

On 02.06.2025 at 18:11, Gina P. Banyard wrote:

The RFC proposes to deprecate implicit type coercions to and from the bool type for other scalar types.
This a "weak" mode change only, as when strict_types are enabled none of these coercions can happen.

Let me know what you think about it.

Let's consider a legacy (PHP 5) function:

    function foo($bool)
    {
        if ($bool) {
            // something
        } else {
            // something else
        }
    }

Now the developer wants to add the missing parameter type declaration.
As is, even without static analysis or a test suite, they can just add
`bool`, being reasonable sure that the code behaves like before for
scalar types, and only fails for non-scalars, something they may be fine
with. With the suggested change, they can no longer, but would rather
have to inspect and possibly "fix" all callers. Since the latter may
not be possible (perhaps because it is an API function), they would just
stick without type declaration, or use the scalar union type. In my
opinion, either is worse than the current type coercion behavior.

Now, one may argue that there should be no boolean parameters at all,
but besides that this is opiniated, maybe it's the reason why the
developer wants to add the type declaration: to be quickly able to
determine boolean parameters, and to move away from those over time.

So, besides that the proposed change would make it harder to bring
legacy code up to date, it likely breaks a ton of code which already
uses `bool` type declarations. That BC break alone is a show-stopper
for me.

Generally, I think that any attempt to unify strict and coercive typing
is futile – that ship has sailed long ago. Those preferring strict
typing likely would not want to compromise, and those preferring
coercive typing will be annoyed by being forced into stricter behavior.

On Tue, June 3, 2025 at 04:29 Christoph M. Becker wrote:

On 02.06.2025 at 18:11, G. P. Banyard wrote:

The RFC proposes to deprecate implicit type coercions to and from the bool type
for other scalar types. This a "weak" mode change only, as when strict_types are
enabled none of these coercions can happen.

Let me know what you think about it.

RFC: PHP: rfc:deprecate-function-bool-type-juggling

Let's consider a legacy (PHP 5) function:

function foo\($bool\)
\{
    if \($bool\) \{
        // something
    \} else \{
        // something else
    \}
\}

Now the developer wants to add the missing parameter type declaration.
As is, even without static analysis or a test suite, they can just add
`bool`, being reasonable sure that the code behaves like before for
scalar types, and only fails for non-scalars, something they may be fine
with. With the suggested change, they can no longer, but would rather
have to inspect and possibly "fix" all callers.

Isn't this already the case? If e.g. someone is passing a nullable string
to the function, adding a `bool` type would cause this to break, which
necessitates inspecting all the callers of the function to make sure null
isn't being passed anywhere.

The proposed RFC doesn't change anything for null, but only deprecates
passing float, string, or int to a `bool` parameter. In my experience,
such usages almost always indicate bugs, and receiving a deprecation
notice would be valuable for fixing them.

In regards to a unified typing mode, personally I don't see any benefit
from `declare(strict_types=1)` anymore, since with static analysis tools
like Psalm strict typing is enforced before even running the code.

Regards,
Theodore

On Monday, 2 June 2025 at 22:05, Rob Landers <rob@bottled.codes> wrote:

No offense, but this feels like it was written by someone who doesn’t use non-strict mode very often.

As yes, saying this to me, someone that is known to have said on stage, multiple times, during talks that

The strict_types declare was a mistake.

Something I even reiterated 7 weeks ago at a Drupal conference. [1]
It would be nice that you don't make assumption about how I write PHP code, as I use weak and strict mode extensively while being annoyed with both modes constantly.
Moreover, even if one uses strict mode one must still know how weak mode behaves as closures/callables do not follow the typing mode in which they have been declared.

The rules around coercion are pretty simple and well documented.

Considering I have given *multiple* talks about PHP's type system and type coercions rules, many people do *not* find them simple or intuitive and get bitten by them constantly.

Further, this makes a ton of shorthand nearly impossible — the manual casting to bool in strict mode is one of the most annoying casts someone has to do (and people screw up order of operations all the time leading to subtle bugs worse than coercion). Bringing this into all of php is probably not a good idea.

It would have been nice to showcase some of these shorthands rather than hiding them behind some sort of mystic as a counterargument.
I really would like to know in which cases you use non-boolean values as argument to boolean parameters.
People creating more subtle and worse bugs due to arbitrary casting is precisely why I want to unify the typing modes, so it's good to know that we think somewhat the same.

Type juggling of strings to bool is similarly error-prone. The strings "" and "0" are converted to false, but "false", " ", and other strings which an (int) cast converts to 0 are coerced to true.

If I understand correctly, you are saying it is weird why the bytes 66 61 6C 73 65 are “true” and 30 is a special case, but not 20? If I remember my history correctly, 30 is special-cased because forms used to send “0” on checkboxes (if it sent it at all; it changed from decade to decade).

I know the reason why we coerce the string "0" to false.
But it is very atypical compared to every other programming language, so yes it is "weird".

I don’t see the benefit of removing this implicit coercion.

The statement is noted.

Regards,
Gina P. Banyard

[1] https://youtu.be/85fgBcV3BuM?t=2832

On Mon, Jun 2, 2025, at 4:02 PM, Rob Landers wrote:

The rules around coercion are pretty
simple and well documented.

Just to note, however simple or not simple they are in 8.4, they are substantially simpler and more logical in 8.4 than they were in 7.0 when strict typing was introduced. And most of that improved simplicity is due to Gina's various RFCs along these lines, which have been highly beneficial even if they sometimes get pushback from the "PHP doesn't care about BC" crowd.

That doesn't inherently mean this RFC is good or bad, but the trend/track record has been squeezing the weirdness out of type juggling until weak mode and strict mode are close enough to touch, and the language is better for it.

--Larry Garfield

On Tue, Jun 3, 2025, at 18:19, Gina P. Banyard wrote:

On Monday, 2 June 2025 at 22:05, Rob Landers rob@bottled.codes wrote:

No offense, but this feels like it was written by someone who doesn’t use non-strict mode very often.

As yes, saying this to me, someone that is known to have said on stage, multiple times, during talks that

The strict_types declare was a mistake.
Something I even reiterated 7 weeks ago at a Drupal conference. [1]
It would be nice that you don’t make assumption about how I write PHP code, as I use weak and strict mode extensively while being annoyed with both modes constantly.
Moreover, even if one uses strict mode one must still know how weak mode behaves as closures/callables do not follow the typing mode in which they have been declared.

Hey Gina,

As mentioned, my intent wasn’t to offend. My goal was to tell you how it read, from my perspective, whether you intended it to or not. As in someone trying to force everyone using weak mode to use strict mode. I’m really sorry that it came across that way, though.

The rules around coercion are pretty simple and well documented.

Considering I have given multiple talks about PHP’s type system and type coercions rules, many people do not find them simple or intuitive and get bitten by them constantly.

That is a fair point. I’ve seen the same confusion among juniors (and sometimes seniors!) over the years. My sense, though, is that some confusion is less about PHP’s type system itself and more about the unique way PHP handles requests compared to other languages. In most languages, frameworks insulate you from the raw request data and make explicit choices about parsing and typing. In PHP, by contrast, you often get the raw bytes, and it is up to you (or your framework, hopefully) to massage that into proper types—which can lead to surprising behaviours if you’re not careful.

I think sometimes people bring expectations from other ecosystems (where, say, the string “false” might have special meaning) and are surprised when PHP treats “false” like any other non-empty string. Maybe that mismatch is the root of a lot of frustrations?

Curious if you see it the same way, or if there is something more fundamental in PHP’s type rules you think causes the confusion?

Further, this makes a ton of shorthand nearly impossible — the manual casting to bool in strict mode is one of the most annoying casts someone has to do (and people screw up order of operations all the time leading to subtle bugs worse than coercion). Bringing this into all of php is probably not a good idea.

It would have been nice to showcase some of these shorthands rather than hiding them behind some sort of mystic as a counterargument.
I really would like to know in which cases you use non-boolean values as argument to boolean parameters.
People creating more subtle and worse bugs due to arbitrary casting is precisely why I want to unify the typing modes, so it’s good to know that we think somewhat the same.

// From a real codebase (sanitized):
$shouldStop = (bool)($result = $service->doSomething($input)) && $result->isError();

This pattern comes up a lot in strict mode: you have to be extra careful with casts and parentheses, or you can end up with subtle bugs like accidentally always returning true/false, or masking null/error values. In looser modes, this just “worked”, but strictness can make it surprisingly easy to trip up.

In my experience, a lot of “non-boolean to boolean” cases are legacy patterns or integrations, but sometimes we’re dealing with values that can be “falsy” in multiple ways (empty array, 0, ‘’, etc.). Sometimes we’re adapting legacy code or writing wrappers that need to accept a wide range of inputs.

The problem, in my view, is that forcing strictness everywhere makes the simple, idiomatic code that worked in PHP for years much more verbose; and potentially more error-prone if the developer isn’t careful with casts or operator precedence.

Type juggling of strings to bool is similarly error-prone. The strings “” and “0” are converted to false, but “false”, " ", and other strings which an (int) cast converts to 0 are coerced to true.

If I understand correctly, you are saying it is weird why the bytes 66 61 6C 73 65 are “true” and 30 is a special case, but not 20? If I remember my history correctly, 30 is special-cased because forms used to send “0” on checkboxes (if it sent it at all; it changed from decade to decade).

I know the reason why we coerce the string “0” to false.
But it is very atypical compared to every other programming language, so yes it is “weird”.

I will 100% agree with you about “0” being false. It was a handy shortcut 20 years ago, but these days it creates more confusion than it solves.

I don’t see the benefit of removing this implicit coercion.

The statement is noted.

Regards,

Gina P. Banyard

[1] https://youtu.be/85fgBcV3BuM?t=2832

— Rob

On 02/06/2025 19:11, Gina P. Banyard wrote:

Hello internals,

This is the first RFC out of a set of type system related RFCs I want to propose for PHP 8.5.
It also used the recently enabled Markdown support on the wiki, so there might be a few oddities.

The RFC proposes to deprecate implicit type coercions to and from the bool type for other scalar types.
This a "weak" mode change only, as when strict_types are enabled none of these coercions can happen.

Let me know what you think about it.

RFC: PHP: rfc:deprecate-function-bool-type-juggling

Best regards,

Gina P. Banyard

Literally 15 minutes ago I caught a nasty bug caused by subj (true becoming 1 and meaning something else entirely). Well, I love the proposition.

On Tuesday, 3 June 2025 at 18:44, Rob Landers <rob@bottled.codes> wrote:

On Tue, Jun 3, 2025, at 18:19, Gina P. Banyard wrote:

On Monday, 2 June 2025 at 22:05, Rob Landers <rob@bottled.codes> wrote:

Further, this makes a ton of shorthand nearly impossible — the manual casting to bool in strict mode is one of the most annoying casts someone has to do (and people screw up order of operations all the time leading to subtle bugs worse than coercion). Bringing this into all of php is probably not a good idea.

It would have been nice to showcase some of these shorthands rather than hiding them behind some sort of mystic as a counterargument.
I really would like to know in which cases you use non-boolean values as argument to boolean parameters.
People creating more subtle and worse bugs due to arbitrary casting is precisely why I want to unify the typing modes, so it's good to know that we think somewhat the same.

// From a real codebase (sanitized):
$shouldStop = (bool)($result = $service->doSomething($input)) && $result->isError();

This pattern comes up a lot in strict mode: you have to be extra careful with casts and parentheses, or you can end up with subtle bugs like accidentally always returning true/false, or masking null/error values. In looser modes, this just “worked”, but strictness can make it surprisingly easy to trip up.

I don't get it, you don't need a bool cast here: Online PHP editor | output for J4BWi

Even with strict_types: Online PHP editor | output for dhnpc

In my experience, a lot of “non-boolean to boolean” cases are legacy patterns or integrations, but sometimes we’re dealing with values that can be “falsy” in multiple ways (empty array, 0, '', etc.). Sometimes we’re adapting legacy code or writing wrappers that need to accept a wide range of inputs.

The problem, in my view, is that forcing strictness everywhere makes the simple, idiomatic code that worked in PHP for years much more verbose; and potentially more error-prone if the developer isn’t careful with casts or operator precedence.

This proposal has no intention of changing the type juggling behaviour of the logical binary operators (and unary ! op) so you shouldn't ever *need* to use both an operator and a cast (even now with strict_types on).

Best regards,
Gina P. Banyard

On 2.06.2025 18:11, Gina P. Banyard wrote:

Let me know what you think about it.

RFC: PHP: rfc:deprecate-function-bool-type-juggling

I would feel better if it targeted PHP9. Right now I'm on +0 on this proposal.

--
Aleksander Machniak
Kolab Groupware Developer [https://kolab.org]
Roundcube Webmail Developer [https://roundcube.net]
----------------------------------------------------
PGP: 19359DC1 # Blog: https://kolabian.wordpress.com

On Wednesday, 4 June 2025 at 14:32, Aleksander Machniak <alec@alec.pl> wrote:

On 2.06.2025 18:11, Gina P. Banyard wrote:

> Let me know what you think about it.
>
> RFC: PHP: rfc:deprecate-function-bool-type-juggling

I would feel better if it targeted PHP9. Right now I'm on +0 on this
proposal.

I don't understand what you mean.
The purpose is to deprecate the behaviour in 8.5 so that it can be removed in PHP 9.
We try to not break behaviour with no prior warning.
Could you clarify what you mean?

Best regards,

Gina P. Banyard

On 4.06.2025 16:03, Gina P. Banyard wrote:

I don't understand what you mean.
The purpose is to deprecate the behaviour in 8.5 so that it can be removed in PHP 9.
We try to not break behaviour with no prior warning.
Could you clarify what you mean?

I meant to move the deprecation to PHP 9.0. I feel the impact of deprecation itself in this case might be significant.

--
Aleksander Machniak
Kolab Groupware Developer [https://kolab.org]
Roundcube Webmail Developer [https://roundcube.net]
----------------------------------------------------
PGP: 19359DC1 # Blog: https://kolabian.wordpress.com

On Wed, June 4, 2025 at 09:37 Aleksander Machniak wrote:

On 4.06.2025 16:03, G. P. Banyard wrote:

I don't understand what you mean.
The purpose is to deprecate the behaviour in 8.5 so that it can be removed in PHP 9.
We try to not break behaviour with no prior warning.
Could you clarify what you mean?

I meant to move the deprecation to PHP 9.0. I feel the impact of
deprecation itself in this case might be significant.

You feel there might be a lot of code passing floats, ints, or strings to
`bool` parameters? I'm doubtful this is the case, since static analysis tools
and IDEs are in much more widespread use nowadays.

In my experience passing non-boolean values to a `bool` parameter almost always
indicates a bug, and it would be valuable to get a deprecation notice sooner
rather than later so these mistakes can be fixed.

Regards,
Theodore

On Wed, Jun 4, 2025, at 11:16 AM, Theodore Brown wrote:

On Wed, June 4, 2025 at 09:37 Aleksander Machniak wrote:

On 4.06.2025 16:03, G. P. Banyard wrote:

I don't understand what you mean.
The purpose is to deprecate the behaviour in 8.5 so that it can be removed in PHP 9.
We try to not break behaviour with no prior warning.
Could you clarify what you mean?

I meant to move the deprecation to PHP 9.0. I feel the impact of
deprecation itself in this case might be significant.

You feel there might be a lot of code passing floats, ints, or strings to
`bool` parameters? I'm doubtful this is the case, since static analysis tools
and IDEs are in much more widespread use nowadays.

In my experience passing non-boolean values to a `bool` parameter almost always
indicates a bug, and it would be valuable to get a deprecation notice sooner
rather than later so these mistakes can be fixed.

Regards,
Theodore

The one place I can see it being used now legitimately is MySQL's TINYINT pseudo-bool columns. If you're mapping your query results into an object (please always do this), then you probably want to cast that into to a bool, and currently weak mode would let you do that implicitly.

I can't think of a case where a string or float magically casting to a bool is reasonable.

--Larry Garfield

On 4.6.2025 18:46:58, Larry Garfield wrote:

On Wed, Jun 4, 2025, at 11:16 AM, Theodore Brown wrote:

On Wed, June 4, 2025 at 09:37 Aleksander Machniak wrote:

On 4.06.2025 16:03, G. P. Banyard wrote:

I don't understand what you mean.
The purpose is to deprecate the behaviour in 8.5 so that it can be removed in PHP 9.
We try to not break behaviour with no prior warning.
Could you clarify what you mean?

I meant to move the deprecation to PHP 9.0. I feel the impact of
deprecation itself in this case might be significant.

You feel there might be a lot of code passing floats, ints, or strings to
`bool` parameters? I'm doubtful this is the case, since static analysis tools
and IDEs are in much more widespread use nowadays.

In my experience passing non-boolean values to a `bool` parameter almost always
indicates a bug, and it would be valuable to get a deprecation notice sooner
rather than later so these mistakes can be fixed.

Regards,
Theodore

The one place I can see it being used now legitimately is MySQL's TINYINT pseudo-bool columns. If you're mapping your query results into an object (please always do this), then you probably want to cast that into to a bool, and currently weak mode would let you do that implicitly.

I can't think of a case where a string or float magically casting to a bool is reasonable.

--Larry Garfield

Basically every time you use external inputs. Maybe it's a $_GET parameter? I mean, I absolutely do not care whether $_GET["showcomments"] is actually 0, foo or 1.23. My code will only assign showcomments=0 or showcomments=1. But all I want is a bool. I absolutely do not care about the actual contents. If the language warns me about that it's likely that I will just be annoyed when it happens occasionally in production when some user tries to play around with the parameter values. And then I'll explicitly add the cast. But for all purposes, it's a plain annoyance.

If you desire to be annoyed, be my guest and use strict types.

For me the whole point of weak types is so that I can easily and comfortably work with arbitrary inputs. So this RFC gets really in my way here and I'm going to vote no on this.

I could get on board with making true|false decay to bool, whenever they appear in an union type. But that's - for me - not related to bool in type juggling.

Bob

On Monday, 2 June 2025 at 17:11, Gina P. Banyard <internals@gpb.moe> wrote:

Hello internals,

This is the first RFC out of a set of type system related RFCs I want to propose for PHP 8.5.
It also used the recently enabled Markdown support on the wiki, so there might be a few oddities.

The RFC proposes to deprecate implicit type coercions to and from the bool type for other scalar types.
This a "weak" mode change only, as when strict_types are enabled none of these coercions can happen.

Let me know what you think about it.

RFC: PHP: rfc:deprecate-function-bool-type-juggling

I have updated the RFC to version 0.2 that expands on it and addresses some of the counterarguments which were said during the discussion.
RFC: PHP: rfc:deprecate-function-bool-type-juggling

If there is no-follow up feedback, I will open the vote for it sometime next week.

Best regards,

Gina P. Banyard

Hi Gina

Le jeu. 26 juin 2025 à 14:07, Gina P. Banyard internals@gpb.moe a écrit :

On Monday, 2 June 2025 at 17:11, Gina P. Banyard internals@gpb.moe wrote:

Hello internals,

This is the first RFC out of a set of type system related RFCs I want to propose for PHP 8.5.
It also used the recently enabled Markdown support on the wiki, so there might be a few oddities.

The RFC proposes to deprecate implicit type coercions to and from the bool type for other scalar types.
This a “weak” mode change only, as when strict_types are enabled none of these coercions can happen.

Let me know what you think about it.

RFC: https://wiki.php.net/rfc/deprecate-function-bool-type-juggling

I have updated the RFC to version 0.2 that expands on it and addresses some of the counterarguments which were said during the discussion.
RFC: https://wiki.php.net/rfc/deprecate-function-bool-type-juggling

If there is no-follow up feedback, I will open the vote for it sometime next week.

Thanks for experimenting with this on https://github.com/symfony/symfony/pull/60890/files

It’s good to see that fitting this RFC requires a relatively small number of lines to change even on a codebase like Symfony. We’re not at 100% but still nice.

Yet, it IS a big bang in terms of deprecations to fix that this will trigger. Their number is super high, because these boolean conversions happen on hotpath / in loops.

This reminds me of the mandatory “?” for arguments with null defaults: the change made sense from a language design PoV, but the impact was, and still is very high. It was and still is a very costly deprecation for the community, and it’s not over yet. That made me say at conferences that this was maybe not a good idea…

Looking at the diff above, I think I can draw two sets of changes:

  1. the ones that patch a cast-to-bool

  2. the ones that patch a cast-from-bool

The latter, cast-from-bool, I think they’re all useful improvements. While most likely harmless in all the specific cases of the PR, doing e.g. an strpos() on false feels hardly legit. I’m therefore sympathetic to making these changes.

For cast-to-bool, I’m WAY less convinced. From the PR above, explicit casts like “return (bool) preg_match(…)” on a method that returns a “bool” or “(bool) ($this->loggedErrors & $type)” are a clear downgrade: it makes the typing PHP just more verbose without any real benefit. That doesn’t look worth asking the whole ecosystem to fix those deprecations. It is especially hard to see this as an improvement when comparing to using the same expressions with e.g. the “if ()” operator, which doesn’t need the explicit cast (and shouldn’t of course).

In the RFC, you write that its motivation is to allow making the bool type equivalent to the true|false union. To do so you propose to make the bool type always behave like in “strict” mode.

Personally, I’m moot about the motivation. I understand it, but it looks inappropriate to push deprecations from this somewhat (IMHO) theoretical angle. The added friction would need way stronger arguments to be justified IMHO.

Would it be possible to trigger the deprecation only in the cast-from-bool direction, and accept casts-to-bool as seamlessly as there are now? If yes, then would it also be possible to make the true and false types have the same behavior (aka non-strict in casts-to-bool direction - when not in strict mode of course)? If yes to both questions, then that’d look like a better outcome that’d still allow fulfilling your goal, while providing maximum value to the community.

As is, the cost/benefit ratio doesn’t make this RFC look worth it to me.

Last but not least, I’m not sure it’s a good idea to rush this into 8.5. This is a high-impact change. We should give some time to the discussion, understand the impact and explore variants. Merging this in 8.6 would also give a few more months for open-source projects to adapt to the change (since many do run their CI with the master branch of PHP to spot changes as early as possible.)

Cheers,
Nicolas

PS: I’m going AFK for the next ~7 days.

Am 26.06.2025 um 14:04 schrieb Gina P. Banyard <internals@gpb.moe>:

On Monday, 2 June 2025 at 17:11, Gina P. Banyard <internals@gpb.moe> wrote:

Hello internals,

This is the first RFC out of a set of type system related RFCs I want to propose for PHP 8.5.
It also used the recently enabled Markdown support on the wiki, so there might be a few oddities.

The RFC proposes to deprecate implicit type coercions to and from the bool type for other scalar types.
This a "weak" mode change only, as when strict_types are enabled none of these coercions can happen.

Let me know what you think about it.

RFC: PHP: rfc:deprecate-function-bool-type-juggling

I have updated the RFC to version 0.2 that expands on it and addresses some of the counterarguments which were said during the discussion.
RFC: PHP: rfc:deprecate-function-bool-type-juggling

If there is no-follow up feedback, I will open the vote for it sometime next week.

The RFC talks about "from" AND "to" bool conversion but the examples under Backward Incompatible Changes only seem mention "from" bool, is that correct?

I tried the implementation in branch bool-juggling-dep-poc on GitHub - Girgias/php-src: The PHP Interpreter and encountered two things:
- php -r 'strlen(false);' produced a core dump with Zend/zend_API.c:561: zend_arg_from_bool_deprecated: Assertion `func->common.fn_flags & (1 << 14)' failed.
- array_slice($a, 1, preserve_keys:"a") did not produce a warning even though I would have thought that is a "to" bool conversion. Am I wrong? What should I test instead?

So far the "from" conversion warnings need changes in very few places in our setup (we very occasionally use false as out-of-band signalling and use the side-effect that strlen() can check both for empty string and false at the same time but that can be easily adapted), our lesson from the nullable parameter that composer packages are the more interesting caveat than our our own but so far nothing popped up.

Summary: I am mostly positive about the "from" part, I don't think I was able to test the "to" part and I'm not sure why I triggered an assertion.

Regards,
- Chris

On Monday, 30 June 2025 at 16:05, Christian Schneider <cschneid@cschneid.com> wrote:

Am 26.06.2025 um 14:04 schrieb Gina P. Banyard internals@gpb.moe:

> On Monday, 2 June 2025 at 17:11, Gina P. Banyard internals@gpb.moe wrote:
>
> > Hello internals,
> >
> > This is the first RFC out of a set of type system related RFCs I want to propose for PHP 8.5.
> > It also used the recently enabled Markdown support on the wiki, so there might be a few oddities.
> >
> > The RFC proposes to deprecate implicit type coercions to and from the bool type for other scalar types.
> > This a "weak" mode change only, as when strict_types are enabled none of these coercions can happen.
> >
> > Let me know what you think about it.
> >
> > RFC: PHP: rfc:deprecate-function-bool-type-juggling
>
> I have updated the RFC to version 0.2 that expands on it and addresses some of the counterarguments which were said during the discussion.
> RFC: PHP: rfc:deprecate-function-bool-type-juggling
>
> If there is no-follow up feedback, I will open the vote for it sometime next week.

The RFC talks about "from" AND "to" bool conversion but the examples under Backward Incompatible Changes only seem mention "from" bool, is that correct?

I didn't think adding examples for "to" bool was useful, but I can add some.

I tried the implementation in branch bool-juggling-dep-poc on GitHub - Girgias/php-src: The PHP Interpreter and encountered two things:
- php -r 'strlen(false);' produced a core dump with Zend/zend_API.c:561: zend_arg_from_bool_deprecated: Assertion `func->common.fn_flags & (1 << 14)' failed.

I forgot to update the optimized strlen opcode, I pushed a fix for this, please pull in the latest version of the branch that has been force pushed.

- array_slice($a, 1, preserve_keys:"a") did not produce a warning even though I would have thought that is a "to" bool conversion. Am I wrong? What should I test instead?

I haven't had time to look at why this is not triggering as it should. But some internal functions do weird stuff sometimes.

So far the "from" conversion warnings need changes in very few places in our setup (we very occasionally use false as out-of-band signalling and use the side-effect that strlen() can check both for empty string and false at the same time but that can be easily adapted), our lesson from the nullable parameter that composer packages are the more interesting caveat than our our own but so far nothing popped up.

Summary: I am mostly positive about the "from" part, I don't think I was able to test the "to" part and I'm not sure why I triggered an assertion.

Regards,
- Chris

Best regards,

Gina P. Banyard

Am 01.07.2025 um 14:40 schrieb Gina P. Banyard <internals@gpb.moe>:

The RFC talks about "from" AND "to" bool conversion but the examples under Backward Incompatible Changes only seem mention "from" bool, is that correct?

I didn't think adding examples for "to" bool was useful, but I can add some.

Thanks!

I tried the implementation in branch bool-juggling-dep-poc on GitHub - Girgias/php-src: The PHP Interpreter and encountered two things:
- php -r 'strlen(false);' produced a core dump with Zend/zend_API.c:561: zend_arg_from_bool_deprecated: Assertion `func->common.fn_flags & (1 << 14)' failed.

I forgot to update the optimized strlen opcode, I pushed a fix for this, please pull in the latest version of the branch that has been force pushed.

Yes, that fixed it for me.

- array_slice($a, 1, preserve_keys:"a") did not produce a warning even though I would have thought that is a "to" bool conversion. Am I wrong? What should I test instead?

I haven't had time to look at why this is not triggering as it should. But some internal functions do weird stuff sometimes.

Not sure if it was a side-effect of the other fix or if you fixed more but the code above now correctly reports a warning.

Thanks again, my evaluation with our code base show very little impact so I'm positive about the change,
- Chris