What is the difference between ?int $number and int $number = null?
If the language were designed today, int $var = null
would probably be an error, and should really be written ?int $var = null
. The two parts mean different things:
- The
?
indicates thatnull
is a valid value for that parameter. - The
= null
indicates thatnull
is the default if the parameter is not passed.
However, before the ?type
syntax was introduced, there was a special case in the language: if null
is given as the default for a parameter, then it is legal to pass null
to that parameter, even if the type declaration would otherwise prevent it.
The difference is how you can call the function:
// public function test(?int $var)
$foo->test("x"); // does not work (Argument 1 passed to Foo::test() must be of the type int or null, string given)
$foo->test(123); // works
$foo->test(null); // works
$foo->test(); // does not work (Too few arguments to function Foo::test(), 0 passed)
// public function test(int $var = null)
$foo->test("x"); // does not work (Argument 1 passed to Foo::test() must be of the type int or null, string given)
$foo->test(123); // works
$foo->test(null); // works
$foo->test(); // works
The difference is that you cannot call the function as ->test()
using the first syntax.
It is important to distinguish between the two language features being discussed here, that is, type declarations and default argument values.
The first function is only using type declarations, this means that the input argument has to be of the type int
or NULL
.
The second function is using both type declarations and default argument values, this means that the argument has to be of the type int
or NULL
but if omitted it will default to NULL
.
Take your first function, if you simply called test()
without passing anything to it, you'd get:
PHP Fatal error: Uncaught ArgumentCountError: Too few arguments to function test() [...]
which is correct as the function expects either int
or NULL
but got neither whereas for the second, as you have defined the argument with a default value, it would run without errors.
Code
function test(?int $var) {
var_dump($var);
}
function test2(int $var = null) {
var_dump($var);
}
test(1); // fine
test(); // error
test2(1); // fine
test2(); // fine
As far as performance goes, the difference is probably negligible, nothing significant enough that would be a cause for concern.
Live Example
Repl