以下代码:
class Type {
}
function foo(Type $t) {
}
foo(null);
运行时失败:
PHP 致命错误:传递给 foo() 的参数 1 不能为空
为什么不允许像其他语言一样传递 null ?
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
及其类型,则可以遵循上面的示例。
您可以阅读更多here。
PHP 7.0 或更早版本
您必须添加一个默认值,例如
function foo(Type $t = null) {
}
这样,您可以传递一个空值。
这在手册中有关 Type Declarations 的部分中有记录:
如果参数的默认值设置为 NULL,则声明可以接受 NULL 值。
从 PHP 7.1 开始,nullable types 作为函数返回类型和参数都可用。类型 ?T
可以具有指定类型 T
或 null
的值。
因此,您的函数可能如下所示:
function foo(?Type $t)
{
}
只要您可以使用 PHP 7.1,就应该优先使用这种表示法而不是 function foo(Type $t = null)
,因为它仍然强制调用者显式指定参数 $t
的参数。
尝试:
function foo(Type $t = null) {
}
正如已经提到的其他答案,这只有在您指定 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);
NullFoo
的编写者重写抽象方法,即使它们没有意义(根据 null
的定义)。
if (something is null)
检查,因为 NullObject 旨在涵盖不存在值的所有行为,并且任何外部合作者都不需要感兴趣对象是否不存在(null)。
自 PHP 8.0 起(2020 年 11 月 26 日发布),您也可以使用 nullable union types。
这意味着您可以将 Type
或 null
作为参数值传递:
function foo(Type|null $param) {
var_dump($param);
}
foo(new Type()); // ok : object(Type)#1
foo(null); // ok : NULL
阅读有关 union types 的更多信息。
就我而言,问题是本机“修剪”功能,它不接受空值。假设您有以下代码:
if (trim($tables) != '')
{
//code
}
PHP8,也抛出这个错误;所以你必须创建一个自定义的“修剪”功能,就像这个一样,让它工作。
public function custom_trim(?string $value)
{
return trim($value ?? '') ;
}
我真的很讨厌这种从 7.4 到 8 的变化
function foo(Type $t)
的事实是一件非常好的事情;见Null References: The Billion Dollar Mistake