On Tue, Feb 22, 2022 at 3:59 AM Alexandru Pătrănescu <dreal...@gmail.com>
wrote:

> On Mon, Feb 21, 2022 at 5:32 PM Craig Francis <cr...@craigfrancis.co.uk>
> wrote:
>
> > On Mon, 21 Feb 2022 at 09:04, Christoph M. Becker <cmbecke...@gmx.de>
> > wrote:
> >
> > > That "inconsistency" had been introduced with PHP 7.0.0, i.e. right
> when
> > > scalar type declarations have been introduced.  Passing a null to a
> > > non-nullable parameter of a *userland* function throws a TypeError
> > >
> >
> >
> > Thanks Christoph, that's a good way of looking at it.
> >
> > Considering NULL has been passed to these internal function parameters
> for
> > years, for a variety of reasons, and PHP has coerced it into an empty
> > string, integer 0, float 0, or boolean false... I'm wondering if my RFC
> > should focus on matching that expectation, so anyone not using
> > `strict_types=1` does not need to make loads of hard-to-find/unnecessary
> > edits; that way NULL would be treated the same as the other variable
> types
> > (I appreciate arrays and objects don't get coerced, but I don't think
> > anyone expects them to).
> >
>
> Yes, exactly that.
> A few weeks ago when the issue was mentioned again I had to remember by
> trying on 3v4l myself that using null for a string parameter wasn't an
> automatically coerced case when strict_types = 0.
>

For history:
https://wiki.php.net/rfc/scalar_type_hints_v5#behaviour_of_weak_type_checks
(**emphasis** mine):

> A weakly type-checked call to an extension or built-in PHP function has
exactly the same behaviour as it did in previous PHP versions.
>
> The weak type checking rules for the new scalar type declarations are
**mostly** the same as those of extension and built-in PHP functions. The
only **exception** to this is the handling of `NULL`: in order to be
**consistent with our existing type declarations for classes, callables and
arrays**, `NULL` is not accepted by default (...)

In hindsight, maybe that wasn't the most "fortunate" decision... (although,
fair enough, `NULL` was never considered to be "scalar")


>
> In my view, false would have the same problem for those internal functions.
> Why should it be coerced to an empty string?
> https://wiki.php.net/rfc/deprecate_null_to_scalar_internal_arg#proposal is
> all about removing the automatic coercion that was happening for null in
> the internal functions
> Planning that in PHP 9 the type interpretation for internal function will
> be done the same as for user defined functions. Consistency.
>
> (...)
>
> As I mentioned, coercing false to int would be for me almost as bad as
> coercing null to int.
> But when types are not considered important I think it's worth pursuing
> extending the coercion from null to the 4 other types where it's happening
> right now:
> - int as 0,
> - float as 0.0,
> - string as an empty string
> - bool as false.
>

Indeed, that could also be a way to solve the original (PHP 7.0)
inconsistency between internal and user-defined functions
(although PHP 8.1 started to take the opposite route...)


>
> I don't like it and I have no good idea how that would work as it would be
> a pretty big BC break.
>
> Maybe it would be easier to change strict_types to default to 1 in PHP 9
> along with adding the null coercion for null when strict_types is 0 rather
> than inventing a new strict_types value like -1 that would allow null
> coercion as well.
> Starting with a notice in PHP 8.2 when the directive is not present might
> be an interesting starting point. And no more warning for implicit coercion
> when strict_types=0 directive is explicitly defined as it would not change
> anymore in PHP 9.
>

Or maybe (if going directly from error to implicit coercion is deemed too
"risky") the current TypeError in non-strict_types mode (when passing NULL
to a user-defined function expecting a scalar) could first be "demoted" to
some kind of Notice [who said E_STRICT] in 8.2 (along with reverting the
Deprecation added in 8.1 for internal functions) and removed in 9.0?

-- 
Guilliam Xavier

Reply via email to