Cannot pass null argument when using type hinting

lx0bsm1f  于 2022-10-22  发布在  PHP
关注(0)|答案(6)|浏览(153)

The following code:

class Type {

}

function foo(Type $t) {

}

foo(null);

failed at run time:
PHP Fatal error: Argument 1 passed to foo() must not be null
Why is it not allowed to pass null just like other languages?

h7wcgrx3

h7wcgrx31#

PHP 7.1 or newer(released 2nd December 2016)

You can explicitly declare a variable to be null with this syntax

function foo(?Type $t) {
}

this will result in

$this->foo(new Type()); // ok
$this->foo(null); // ok
$this->foo(); // error

So, if you want an optional argument you can follow the convention Type $t = null whereas if you need to make an argument accept both null and its type, you can follow above example.
You can read more here .

PHP 7.0 or older

You have to add a default value like

function foo(Type $t = null) {

}

That way, you can pass it a null value.
This is documented in the section in the manual about Type Declarations:
The declaration can be made to accept NULL values if the default value of the parameter is set to NULL .

s5a0g9ez

s5a0g9ez2#

Starting from PHP 7.1, nullable types are available, as both function return types and parameters. The type ?T can have values of the specified Type T , or null .
So, your function could look like this:

function foo(?Type $t)
{

}

As soon as you can work with PHP 7.1, this notation should be preferred over function foo(Type $t = null) , because it still forces the caller to explicitly specify an argument for the parameter $t .

ygya80vv

ygya80vv3#

Try:

function foo(Type $t = null) {

}

Check out PHP function arguments .

zbdgwd5y

zbdgwd5y4#

As of PHP 8.0(released November 26, 2020), you can also use thenullable union types.

This means that you are allowed to pass either Type or null as the parameter value:

function foo(Type|null $param) {
    var_dump($param);
}

foo(new Type()); // ok : object(Type)#1
foo(null);       // ok : NULL

Read more about union types.

yx2lnoni

yx2lnoni5#

As other answers already mentioned, this is only possible if you specify null as the default value.
But the cleanest type-safe object oriented solution would be a NullObject :

interface FooInterface
{
    function bar();
}
class Foo implements FooInterface
{
    public function bar()
    {
        return 'i am an object';
    }
}
class NullFoo implements FooInterface
{
    public function bar()
    {
        return 'i am null (but you still can use my interface)';
    }
}

Usage:

function bar_my_foo(FooInterface $foo)
{
    if ($foo instanceof NullFoo) {
        // special handling of null values may go here
    }
    echo $foo->bar();
}

bar_my_foo(new NullFoo);
qoefvg9y

qoefvg9y6#

In my case, the problem was the native "trim" function, that not accepts null. Let's suppose that you've this code:

if (trim($tables) != '') 
{
 //code 
}

PHP8 will throws you this error; so you if you're working on a legacy code, I suggest you to create a custom "trim" function, like this one, to make it work quickly.

public function custom_trim(?string $value)
  {
    return trim($value ?? '') ;
  }

I really hate this change from 7.4 to 8

相关问题