最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 再次学习方法参数类型声明

    正文概述 转载于:掘金(硬核项目经理)   2021-03-25   103

    不管从事什么行业,现在都是活到老学到老的趋势,特别是我们这堆码农。这回也不用说新技术用不上,光光是php文档的学习都会发现非常多的知识点其实自己并没有真正的掌握,比如说这个方法参数的类型声明。上次文章中,关于PHP的方法参数类型约束,我们说过方法参数的类型约束仅限于类、接口、数组或者callable回调函数,其实这是不严谨的,PHP中也有一个严格模式的定义,如果指定了严格模式的话,普通的为方法参数类型指定普通的标量类型也是有效果的。

    严格模式的定义:

    declare (strict_types = 1);
    

    int 类型

    function testInt(int $a)
    {
        echo $a, PHP_EOL;
    }
    
    testInt(1);
    // testInt(1.1); // Fatal error: Uncaught TypeError: Argument 1 passed to testInt() must be of the type int
    // testInt('52AABB'); // Fatal error: Uncaught TypeError: Argument 1 passed to testInt() must be of the type int
    // testInt(true); // Fatal error: Uncaught TypeError: Argument 1 passed to testInt() must be of the type int
    

    在严格模式下,很明显地看出现在这个方法的参数只能接收 int 类型的值了,其他的类型都无法接收,当然也不会像之前文章说过的那样会发生强制转换。

    float 类型

    function testFloat(float $a)
    {
        echo $a, PHP_EOL;
    }
    
    testFloat(1);
    testFloat(1.1);
    // testFloat('52AABB'); // Fatal error: Uncaught TypeError: Argument 1 passed to testInt() must be of the type int
    // testInt(true); // Fatal error: Uncaught TypeError: Argument 1 passed to testInt() must be of the type int
    

    这里需要注意的是,PHP只有 int 和 float,而且 float 是 int 的超集,所以这里是可以传整数过来的,不过上面的 testInt(int $a) 则不能接收 1.1 这样的 float 值。这就涉及到了上下转换的问题,向超集转换是OK的,但是超集向子集转换是就不OK了。

    string 类型

    function testString(string $a)
    {
        echo $a, PHP_EOL;
    }
    
    // testString(1);  // Fatal error: Uncaught TypeError: Argument 1 passed to testString() must be of the type string
    // testString(1.1);  // Fatal error: Uncaught TypeError: Argument 1 passed to testString() must be of the type string
    testString('52AABB');
    // testString(true); // Fatal error: Uncaught TypeError: Argument 1 passed to testString() must be of the type string
    

    这个就不用过多解释了,在非严格模式下我们如果定义 string 类型的接收参数的话,其实是任何类型都可以接收过来做为 string 类型的,这里的类型转换就不多说了,可以说在非严格模式下定义 string 类型的效果跟没有任何定义是一样的。但是严格模式下就不同了,真的是只能接收双引或者单引号之内的字符串内容。

    bool 类型

    function testBool(bool $a)
    {
        var_dump($a);
    }
    testBool(true);
    testBool(false);
    // testBool('52AABB'); // Fatal error: Uncaught TypeError: Argument 1 passed to testBool() must be of the type bool
    // testBool(1); // Fatal error: Uncaught TypeError: Argument 1 passed to testBool() must be of the type bool
    

    布尔值也是同理的,这里我们也只能接收 true 和 false 关键字的值。

    新学习一个 iterable 类型

    最后来介绍个新家伙,除了普通模式下的类、数组、回调函数,严格模式下的各种标量类型声明外,还有一个 iterable 类型的声明,相信大家通过这个单词也能看出来了,可迭代的类型。

    function testIterable(iterable $iterator)
    {
        echo gettype($iterator), ':', PHP_EOL;
        foreach ($iterator as $it) {
            echo $it, PHP_EOL;
        }
    }
    
    testIterable([1, 2, 3]);
    testIterable(new ArrayIterator([1, 2, 3]));
    // Generator对象
    testIterable((function () {
        yield 1;
        yield 2;
        yield 3;
    })());
    // testIterable(1); // Fatal error: Uncaught TypeError: Argument 1 passed to testIterable() must be iterable
    

    没错,它包含了数组、实现迭代器接口的类以及生成器相关的内容。也就是所有可用 foreach 迭代的内容都可以传递过来。生成器本身会是一个 Generator 对象,而在学习PHP生成器的使用这篇文章中,我们已经看过这个 Generator 对象的内容,它本身也是实现了 Iterator 接口。

    总结

    就像开头说过的,原来在严格模式下我们的语法还会有这么大的差异,这回真的是长见识了。我们的学习之路还很长,也希望各位能够持续关注一起加油!!

    测试代码:

    github.com/zhangyue050…

    参考文档:

    《PHP7编程实战》 wiki.php.net/rfc/scalar_… www.php.net/manual/zh/c… wiki.php.net/rfc/iterabl…


    起源地 » 再次学习方法参数类型声明

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元