Cannot pass null argument when using type hinting

100,470

Solution 1

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.

Solution 2

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.

Solution 3

Try:

function foo(Type $t = null) {

}

Check out PHP function arguments.

Solution 4

As of PHP 8.0 (released November 26, 2020), you can also use the nullable 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.

Solution 5

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);
Share:
100,470

Related videos on Youtube

Abdullah
Author by

Abdullah

Updated on July 08, 2022

Comments

  • Abdullah
    Abdullah almost 2 years

    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?

  • crush
    crush over 11 years
    The problem I have with this is that it changes the definition of the function. Now the parameter is optional - which isn't really what the author intended (although, if he is passing it null, it is implicitly optional).
  • Pacerier
    Pacerier almost 11 years
    So why isn't null the null object?
  • Henry
    Henry almost 10 years
    Most languages allow null to have any type. In this scenario.
  • Henry
    Henry over 8 years
    In my opinion this is a poor language construct. 1. In other languages null has the ability to be of any type thus making null a valid argument in this case. 2: Php is using a default value for an argument to specify that null is allowable, this is obscure and it makes a mandatory parameter impossible even if the developer wants to force a null to be explicitly passed.
  • Force Hero
    Force Hero almost 8 years
    I agree with @Henry, in addition it looks weird to have required params after what looks like an optional param.
  • Constantin Galbenu
    Constantin Galbenu almost 8 years
    I agree with @Henry only on 2. Regarding 1 the fact that you can't pass null to function foo(Type $t) is a VERY good thing; see Null References: The Billion Dollar Mistake
  • TheOperator
    TheOperator over 7 years
    This approach is often impractical, because instead of 1 class, you now need 3. Also, it forces the writer of NullFoo to override abstract methods, even though they have no meaning (by definition of null).
  • lost
    lost about 6 years
    In my experience the NullObject pattern can be practical, if you work in general in a very strict, classical OO way. In the answer, imo the NullObject pattern is a bit abused, as it is especially meant to avoid if (something is null) checks, as the NullObject is meant to cover all behavior of a non-existing value and any outside collaborator should not need to be interested in whether an object is non-existing (null) or not.
  • Roberto Maldonado
    Roberto Maldonado over 5 years
    @ConstantinGalbenu If you say that 1 is a very good thing, wouldn't that make 2 a "extremely good thing"? I mean, you have to declare explicitly where you want a null value, thus avoiding null surprises. Then why is that a bad thing?
  • Constantin Galbenu
    Constantin Galbenu over 5 years
    @RobertoMaldonado As of PHP 7.1 you can put ?T as a type hint so his 2nd point is not 100% valid any more.
  • Roberto Maldonado
    Roberto Maldonado over 5 years
    @ConstantinGalbenu Oh right. I god messed up lol. I thought you were refering to OP points instead of Henry's. Still, in summary, explicitly declaring a null-accepting variable should be a good thing too IMO.
  • Constantin Galbenu
    Constantin Galbenu over 5 years
    @RobertoMaldonado yes, for example, when the business rules demand it
  • Constantin Galbenu
    Constantin Galbenu over 5 years
    @RobertoMaldonado the main idea is that it is explicit; before PHP 7.1 one must also set a default null when he wants only the possibility of receiving a null value