从PHP 7.0开始,标量类型提示int,float,string和bool可以包含在方法签名中.默认情况下,这些类型声明以弱/强制模式(或“type juggling”模式)运行.根据PHP manual:
PHP will coerce values of the wrong type into the expected scalar type if possible. For example, a function that is given an integer for a parameter that expects a string will get a variable of type string.
但即使可以将NULL强制转换为整数0,具有int typehint的方法也会拒绝将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
类似地,即使it is possible将NULL强制转换为布尔值false,带有bool typehint的方法也会拒绝将NULL的入站值强制转换为布尔值false.浮点数和字符串类型提示也是如此.
这种行为似乎与PHP.net上的文档相矛盾.这里发生了什么?
解决方法:
目前无法允许具有标量类型提示的方法自动将juggle入站NULL值键入声明的类型.
The weak type checking rules for the new scalar type declarations are mostly (emphasis added) the same as those of extension and built-in PHP functions. The only exception to this is the handling of NULL: in order to be consistent with our existing type declarations for classes, callables and arrays, NULL is not accepted by default, unless it is a parameter and is explicitly given a default value of 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!