php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #75312 Scalar typed variadic arguments accept other scalars but not null
Submitted: 2017-10-05 09:19 UTC Modified: 2022-04-22 13:21 UTC
Votes:1
Avg. Score:1.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: michelv+php at gmail dot com Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 7.1.10 OS: all
Private report: No CVE-ID: None
 [2017-10-05 09:19 UTC] michelv+php at gmail dot com
Description:
------------
Typed variadic arguments are now possible, but it looks like some duck-typing is still going on, because you can use integers or booleans for arguments like `string ...$args`. However you can not use null, that results in a fatal error.

If duck-typing should not happen at all, being able to use anything other than a string in that case is a bug.

If duck-typing is expected, then it's not working like it does in other parts of PHP, where null is accepted.

Test script:
---------------
<?php

function vsprintfProxy(string $format, string ...$args): string
{
    return vsprintf($format, $args);
}

var_export(vsprintf('%s', [42]));
var_export(vsprintfProxy('%s', 42));
echo "\n";

var_export(vsprintf('%s', [false]));
var_export(vsprintfProxy('%s', false));
echo "\n";

var_export(vsprintf('%s', [null]));
var_export(vsprintfProxy('%s', null));
echo "\n";

Expected result:
----------------
'42''42'
''''
''''

Actual result:
--------------
'42''42'
''''
''
Fatal error: Uncaught TypeError: Argument 2 passed to vsprintfProxy() must be of the type string, null given, called in /in/pNqSi on line 17 and defined in /in/pNqSi:3
Stack trace:
#0 /in/pNqSi(17): vsprintfProxy('%s', NULL)
#1 {main}
 thrown in /in/pNqSi on line 3

Process exited with code 255.


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-10-05 09:48 UTC] spam2 at rhsoft dot net
in which other parts of PHP is NULL allowed in that case unless 7.1.x and explicit ?string instead only string

what you obviously want is strict typing, well than declare that in the first line of your files
 [2017-10-05 10:07 UTC] requinix@php.net
-Summary: inconsistent duck-typing with typed variadic arguments +Summary: Scalar typed variadic arguments accept other scalars but not null -Type: Bug +Type: Documentation Problem
 [2017-10-05 10:07 UTC] requinix@php.net
This is loose typing, not duck typing.

Variadics typing follows the same rules as non-variadic typing:
> The declaration can be made to accept NULL values if the default value of the
> parameter is set to NULL.
and
> By default, PHP will coerce values of the wrong type into the expected scalar
> type if possible. For example, a function that is given an integer for a
> parameter that expects a string will get a variable of type string.
http://php.net/manual/en/functions.arguments.php
Also https://wiki.php.net/rfc/scalar_type_hints_v5#behaviour_of_weak_type_checks

However the first part isn't possible for a variadic parameter so I think the "Variable-length argument lists" section should mention that NULLs aren't allowed.

At least not normally. The answer to that use case was the introduction of nullable types ("?string ...$args") but I can't find them documented anywhere besides the migration guide...
https://wiki.php.net/rfc/nullable_types
http://php.net/manual/en/migration71.new-features.php#migration71.new-features.nullable-types

And as @spam2 said, it sounds like you want strict_types.
http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration.strict
 [2017-10-05 11:36 UTC] michelv+php at gmail dot com
My bad, I'm so used to having strict types declared that I forgot to declare them in 3v4l when I tested the functionality.

Thanks for the clarification!
 [2022-04-22 13:21 UTC] ilutov@php.net
-Status: Open +Status: Not a bug
 [2022-04-22 13:21 UTC] ilutov@php.net
We have nullable types now which work for variadics. An error when passing null to a non-nullable string argument is correct.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 14 07:01:27 2024 UTC