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

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值键入声明的类型.

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

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!

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...