On Tue, 1 Mar 2022 at 14:12, Kamil Tekiela <tekiela...@gmail.com> wrote:

> Hi Craig,
>
> > No, there is an inconsistency which leads to a backwards compatibility
> issue, and I'm trying to fix it.
>
> Which inconsistency exactly do you have in mind?
>


Ok, let's try with code (I'll skip using variables):

https://3v4l.org/gvXmr

<?php

var_dump(strtoupper(1));
var_dump(strtoupper(1.2));
var_dump(strtoupper(false));
var_dump(strtoupper('a'));
var_dump(strtoupper(NULL));

var_dump(strtoupper(''   == ''));
var_dump(strtoupper(NULL == ''));

?>

Before PHP 8.1 all 5 forms of coercion worked for those not using
strict_types... now a form of coercion (from NULL) has been deprecated, and
for some reason it's likely to trigger a Fatal Error for everyone in 9.0
(while this is appropriate for those using strict_types, who are typically
using static analysis; it's not appropriate for everyone else).



The discussion is about passing arguments to functions. We are not
> discussing type juggling or type casting. To clarify the whole thing let's
> list out the key points:
>
> - PHP has a concept of scalar types consisting of these four types:
> string, int, float, bool
>


But I am talking about Type Juggling:

https://www.php.net/manual/en/language.types.type-juggling.php

Or as noted under the Strict Typing documentation, where I've been using
the name "coercion":

https://www.php.net/manual/en/language.types.declarations.php#language.types.declarations.strict

Anyway, as noted earlier, developers who are not using `strict_types`, they
do not care about PHP's definition of what a scaler is... they don't
generally think about variable types (ish), and they don't really see type
coercion happening, they just expect it to work... yet, in 8.1, coercing
from NULL with internal functions is now deprecated (still works with
non-strict comparison operators though).


The only inconsistency is that PHP's internal functions silently accepted
> NULL values for non-nullable parameters. This will be addressed in PHP 9.0.
>


Adding a type check for scripts not using `strict_types` it will make it
much harder for developers to upgrade to PHP 9 (not good).

While sticking strval() everywhere in itself is an easy change, due to the
numbers, and difficulty in finding them (note the lack of tooling), it's
very time consuming to update (your code may be fine, but that's not
common).


Changing the signatures of some functions might be reasonable but, as few
> others have said, it's not the solution we want to see because it feels
> like a hack. As I have also pointed out off-list, in many cases making the
> parameter type nullable would not make any sense as passing null to certain
> functions is a clear bug. It would also have an impact on strict typing!
>


Yep, I agree, see previous emails.


We could also reclassify NULL as a scalar type but that would be a
> fundamental language change. It would likely be a bigger BC change than
> fixing the current inconsistency.
>


I doubt we need to change the definition - I doubt many people would care
what the documentation says, and there is no need to modify the output of
`is_scalar()`, even if I personally find it a bit weird (but this isn't
about me).

We need to accept that PHP has coerced NULL to an empty string, integer 0,
float 0, and boolean false since, well, forever... and developers not using
strict_types have used this feature all the time (nearly always without
thinking about it).


By the way, your statement that "Coercion works for string/int/float/bool,
> *and* NULL." is invalid. Coercion is defined only for scalar types as I
> have explained above. Type juggling for most types from NULL is defined,
> but that is not what we are discussing.
>


Erm, we are discussing type juggling "from NULL"... as in, NULL is being
provided to these functions, and the value is coerced from NULL to a
string/int/float/bool, as documented:

https://www.php.net/manual/en/language.types.string.php
"null is always converted to an empty string."

https://www.php.net/manual/en/language.types.integer.php
"null is always converted to zero (0)."

https://www.php.net/manual/en/language.types.float.php
"For values of other types, the conversion is performed by converting the
value to int first and then to float"

https://www.php.net/manual/en/language.types.boolean.php
"When converting to bool, the following values are considered false [...]
the special type NULL"

Craig

Reply via email to