使用类型提示时无法传递空参数


192

如下代码:

<?php

    class Type {

    }

    function foo(Type $t) {

    }

    foo(null);

?>

在运行时失败:

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

为什么不允许像其他语言一样传递null?

Answers:


355

PHP 7.1或更高版本(2016年12月2日发布)

您可以null使用此语法显式声明一个变量

function foo(?Type $t) {
}

这将导致

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

因此,如果您想要一个可选参数,则可以遵循约定,Type $t = null而如果需要使一个参数接受null及其类型,则可以遵循上面的示例。

您可以在这里阅读更多内容。


PHP 7.0以上

您必须添加一个默认值,例如

function foo(Type $t = null) {

}

这样,您可以将其传递为空值。

这在手册中有关类型声明的部分中进行了记录:

NULL如果参数的默认值设置为,则声明可以接受值NULL


10
那么为什么不将null对象设为null呢?
Pacerier

4
大多数语言都允许null具有任何类型。在这种情况下。
亨利

24
我认为这是一种糟糕的语言结构。1.在其他语言中,null可以是任何类型,因此在这种情况下可以使null为有效参数。2:Php使用默认值作为参数来指定允许使用null,这是晦涩的,即使开发人员要强制显式传递null,也使强制参数成为不可能。
亨利

2
我同意@Henry,此外,在看起来像是可选参数之后,需要参数是很奇怪的。
Force Hero

6
我只同意@Henry。2。关于1不能将null传递给function foo(Type $t)我们的事实是一件非常好的事情;参见Null参考:十亿美元的
失误

35

从PHP 7.1开始,可空类型可以用作函数返回类型和参数。该类型?T可以具有指定Type的值T,或者null

因此,您的函数可能如下所示:

function foo(?Type $t)
{

}

一旦可以使用PHP 7.1,就应该优先使用这种表示法function foo(Type $t = null),因为它仍然会强制调用者为parameter显式指定一个参数$t


12

尝试:

function foo(Type $t = null) {

}

查看PHP函数参数


11
我的问题是它会更改函数的定义。现在该参数是可选的-并不是作者真正想要的(尽管,如果他将其传递为null,则它是隐式可选的)。
粉碎了

7

正如已经提到的其他答案一样,只有在您指定 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);

1
这种方法通常是不切实际的,因为您现在需要3来代替1类,而且,它迫使作者NullFoo重写抽象方法,即使它们没有任何意义(根据的定义null)。
TheOperator'Nov

1
以我的经验,如果您通常以非常严格的经典OO方式工作,则NullObject模式可能是实用的。在答案中,imo NullObject模式被滥用了一点,因为它特别是为了避免if (something is null)检查,因为NullObject旨在涵盖不存在值的所有行为,并且任何外部合作者都不需要关心是否存在对象不存在(空)或不存在。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.