Re: NULL Coercion Consistency
| From: | Craig Francis | Date: | Wed, 27 Apr 2022 17:34:36 +0000 |
| Subject: | Re: NULL Coercion Consistency | ||
| References: | 1 2 3 4 5 6 7 8 9 10 11 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-117638@lists.php.net to get a copy of this message | ||
On 26 Apr 2022, at 21:11, Rowan Tommins <rowan.collins@gmail.com> wrote:
>
> On 26/04/2022 17:36, Guilliam Xavier wrote:
>> function mt_rand(int $min = UNKNOWN, int $max = UNKNOWN): int {}
>>
>> documented with two signatures at
>> https://www.php.net/manual/en/function.mt-rand.php
>>
>> mt_rand(): int
>> mt_rand(int $min, int $max): int
>
>
> This is actually a really pertinent example: you might expect mt_rand(null, null) to give the
> same behaviour as mt_rand(), but actually it will always return 0, because it silently coerces to
> mt_rand(0, 0). That's exactly the kind of unexpected behaviour type checking aims to protect
> against.
First, thanks Guilliam for the examples.
And Rowan, I agree it's a good example, and I've added it to the Open Issues.
But I'm wondering, is it only one function? and assuming it's a problem, could we use
Z_PARAM_LONG_OR_NULL() and specifically throw an exception when either parameter is
NULL, like the max < min check? On the basis that I'd rather have one extra
check for this function, and keep NULL coercion working everywhere else (i.e. where it's fine).
As an aside, under the Future Scope:
https://wiki.php.net/rfc/null_coercion_consistency#future_scope
I'd noted some functions that could do with some similar changes, but that's more about
copying the example of $separator in explode() and the “cannot be
empty” error, so NULL or an Empty String is rejected (rather than just rejecting NULL).
> There used to be a lot more functions with pseudo-defaults like this, but a lot were made to
> accept null in PHP 8.0. e.g. mb_convert_encoding('foo', 'ASCII', null) now acts
> like mb_convert_encoding('foo', 'ASCII') and looks up a run-time default; but in
> previous versions it acted as mb_convert_encoding('foo', 'ASCII', '')
> which is not a valid call.
Thanks, that's another good example, but I'm going to be a pain, and would suggest that
the specific function was correctly updated to work with NULL (and anyone who did pass NULL to that
argument, would have had the "must specify at least one encoding" error).
Craig