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