Невозможно передать нулевой аргумент при использовании типа hinting

Следующий код:

<?php

    class Type {

    }

    function foo(Type $t) {

    }

    foo(null);

?>

не удалось во время выполнения:

PHP Fatal error:  Argument 1 passed to foo() must not be null

Почему не разрешено передавать null так же, как и другие языки?

Ответ 1

Вам нужно добавить значение по умолчанию, например

function foo(Type $t = null) {

}

Таким образом, вы можете передать ему нулевое значение.

Это описано в разделе, посвященном Объявлениям типа:

Объявление может быть принято для принятия значений NULL, если значение по умолчанию для параметра установлено на NULL.

Из PHP 7.1 (выпущен 2 декабря 2016 года) вы можете явно объявить переменную как NULL с этим синтаксисом

function foo(?Type $t) {
}

это приведет к

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

Итак, если вам нужен дополнительный аргумент, вы можете следовать за соглашением Type $t = null, тогда как если вам нужно сделать аргумент, принимающий как NULL, так и его тип, вы можете следовать приведенному выше примеру.

Здесь вы можете прочитать .

Ответ 2

Начиная с PHP 7.1, типы с нулевым значением доступны как типы возвращаемых функций, так и параметры. Тип ?T может иметь значения указанного типа T или null.

Итак, ваша функция может выглядеть так:

function foo(?Type $t)
{

}

Как только вы сможете работать с PHP 7.1, это обозначение должно быть предпочтительнее, чем function foo(Type $t = null), поскольку оно по-прежнему вынуждает вызывающего пользователя явно указывать аргумент для параметра $t.

Ответ 4

Как уже упоминалось, это возможно только в том случае, если в качестве значения по умолчанию указано null.

Но самым чистым объектно-ориентированным решением будет 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)';
    }
}

Использование:

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);