PHP7:具有标量类型声明的方法拒绝类型处理 NULL 值,即使在弱/强制模式下也是如此



从 PHP 7.0 开始,标量类型提示intfloatstringbool可以包含在方法签名中。 默认情况下,这些类型声明在弱/强制模式(或"类型处理"模式(下运行。 根据PHP手册:

如果可能,PHP 会将错误类型的值强制转换为预期的标量类型。例如,为需要字符串的参数提供整数的函数将获得字符串类型的变量。

但是,即使可以将 NULL 强制转换为整数 0,具有int类型提示的方法也会拒绝将入站值NULL强制转换为整数 0。

<?php
class MyClass
{
public function test(int $arg)
{
echo $arg;
}
}
$obj = new MyClass();
$obj->test('123'); // 123
$obj->test(false); // 0
$obj->test(null);  // TypeError: Argument 1 passed to MyClass::test()
// must be of the type integer, null given

类似地,即使可以将 NULL 强制到布尔false中,具有bool类型提示的方法也会拒绝NULL的入站值强制到布尔falsefloatstring类型提示也是如此。

此行为似乎与有关 php.net 的文档相矛盾。 这是怎么回事?

目前无法允许具有标量类型提示的方法自动将杂耍入站 NULL 值键入到声明的类型。

根据负责将此功能引入 PHP 7 的 RFC:

新标量类型声明的弱类型检查规则大多(强调添加(与扩展和内置 PHP 函数的规则相同。唯一的例外是 NULL 的处理:为了与我们现有的类、可调用对象和数组的类型声明保持一致,默认情况下不接受 NULL,除非它是一个参数并且显式给定默认值 NULL。

但是,在以下情况下,NULL 值可以作为 NULL 接受:

<?php
class MyClass
{
// PHP 7.0+
public function testA(int $arg = null)
{
if (null === $arg) {
echo 'The argument is NULL!';
}
}
// PHP 7.1+
// https://wiki.php.net/rfc/nullable_types
public function testB(?int $arg)
{
if (null === $arg) {
echo 'The argument is NULL!';
}
}
}
$obj = new MyClass();
$obj->testA(null); // The argument is NULL!
$obj->testB(null); // The argument is NULL!

最新更新