On Tue, Apr 26, 2022 at 12:54 PM Andreas Leathley <a.leath...@gmx.net>
wrote:

> Hello Internals,
>
> Implicit type coercions (when not using strict_types) have become
> increasingly less lossy/surprising in PHP, especially coercions to
> integer and float, where you get a TypeError if you pass a non-numeric
> string to an integer parameter, and a deprecation notice if you pass a
> float(-string) with a fractional part to an integer parameter. The big
> exception so far is coercions to boolean, where you can provide any
> scalar value and never get an error or a notice.
>
> Any non-empty string (except "0") is converted to true and any non-zero
> integer or float is converted to true. From my perspective this can
> easily lead to hidden bugs, for example when passing the wrong variable
> to a boolean argument or boolean property. Passing a string like "hello"
> as a boolean is probably a bug, just like passing the number 854 or the
> float 0.1 . "on" and "off" and "true" and "false" all lead to a boolean
> true, as examples of strings that could be used in applications and
> might not all be meant as a value of true.
>
> I have not found any past proposals or discussions to change boolean
> coercions, so I would like to find out how the thoughts on internals are
> to change this, or if there are any reasons not to change this that I
> have not thought of. Only allowing the following values would make sense
> from my perspective:
>
> '1' => true
> 1 => true
> 1.0 => true
> '' => false
> '0' => false
> 0 => false
> 0.0 => false
>
> I can also see a case for allowing the strings 'true' and 'false', and
> changing 'false' to be coerced to false, but that would be a BC break. I
> am not sure if that is worthwhile.
>
> Anything else would emit either a notice or a warning as a first step
> (to be determined). My main goal would be to make these
> probably-not-boolean usages more visible in codebases. Depending on the
> feedback here I would create an RFC and try to do an implementation (to
> then discuss it in more detail), so as of now this is mostly about
> getting some basic feedback on such a change, and if someone else has
> had any similar thoughts/plans.
>

I thought about coercion on parameters, return value and property types a
few weeks ago as well, both to and from bool:
In my opinion, only int should be coerced:
- bool to int: false to 0 and true to 1
- int to bool: 0 to false and anything else to true
That's because sometimes boolean values are stored numerically as 0 or 1.

What can be coerced but it might be good to remove as well:
- int numeric string to bool: '0' to false and anything else to true,
validity of a int numeric string, being considered the same as when
coercing string to int (empty string is not valid).

What should not be coerced:
- bool to string: false to '' and true to '1'
- string to bool: '' to false and anything else to true
- bool to float: false to 0.0 and true to 1.0
- float to bool: 0.0 to false and anything else to true
To me, all of these look like possible bugs and an explicit conversion
should be used if correctly intended.

Other types already raise errors to and from bool:
null|object|resource|array.

In terms of RFC, it would be pretty controversial as there's a lot of BC
breaks.
"bool to string" and "bool to float" are probably the most clear cases.

I have no plans to initiate a RFC in the near future, just sharing my
thoughts about it mostly.

Regards,
Alex

Reply via email to