关于declare(strict_types=1)的有效范围

栏目: PHP · 发布时间: 5年前

内容简介:declare(strict_type=1);是php7引入的在此状态下执行独立时,输出我们提供的是

declare(strict_type=1);是 php 7引入的 严格类型检查模式 的指定语法

单个文件时 strict_types 应写在哪里

基本语法

<?php
function add(int $a, int $b): int
{
    return $a + $b;
}

var_dump(add(1.0, 2.0));

在此状态下执行独立时,输出 int(3)

我们提供的是 double 类型,但 php7 能很好的处理它,和 php5 时代没什么区别

做了如下变更

<?php
declare(strict_types=1);    //加入这句

function add(int $a, int $b): int
{
    return $a + $b;
}

var_dump(add(1.0, 2.0));

TypeError 产生,如下

PHP Fatal error:  Uncaught TypeError: Argument 1 passed to add() must be of the type integer, float given, called in /Users/hiraku/sandbox/stricttypes/A.php on line 9 and defined in /Users/hiraku/sandbox/stricttypes/A.php:4
Stack trace:
#0 /Users/hiraku/sandbox/stricttypes/A.php(9): add(1, 2)
#1 {main}
  thrown in /Users/hiraku/sandbox/stricttypes/A.php on line 4

strict_types 不能写在脚本中间

declare 语法不能写在脚本的中间,如下写法是错误的

<?php
function add(int $a, int $b): int
{
    return $a + $b;
}

declare(strict_types=1);

var_dump(add(1.0, 2.0));

产生如下错误

PHP Fatal error:  strict_types declaration must be the very first statement in the script in /Users/hiraku/sandbox/stricttypes/A.php on line 7

Fatal error 产生,这甚至不是 Throwable ,而是编译过程中产生的错误

同样,与上述例子相似的位置,也不能使用如下语法

<?php
declare(strict_types=1) {
  //...
}
PHP Fatal error:  strict_types declaration must not use block mode in /Users/hiraku/sandbox/stricttypes/A.php on line 2

两个文件时 strict_types 如何产生作用

如下代码

A.php 脚本在开头声明严格模式

A.php脚本

<?php
declare(strict_types=1);
function add(int $a, int $b): int
{
    return $a + $b;
}

A.phpB.php 文件 require ,如下

B.php脚本

<?php
require 'A.php';
var_dump(add(1.0, 2.0));    //注意这里键入的是1.0和2.0浮点数,而A.php声明需要int

执行结果

$ php B.php
int(3)

什么!!!!居然能够执行而不报错!!!!!

原来是 B.php 并没有声明 strict_types ,所以对于B脚本来说,是默认的松散模式

也就是说,对于 strict_types 有以下的行为

  • 不管怎么样,函数定义时的严格模式,行为并不会出现什么不同
  • 函数执行时的,严格模式会出现差异
  • declare(strict_types=1); 的语法本身在 A.php 文件中完成,而被 B.php 文件 require ,而 B.php 并没有定义严格模式,那么执行 require 的文件( B.php )不会变成严格模式

上述解释就如如下代码所示,理论上 A.php 文件的严格模式已经关闭了,然而仅仅是 B.php 文件设定了 declare(strict_types=1); ,那么即使 A.php 没有设定严格模式,但 A.phpB.php 引用了,就对 A.php 使用严格模式

A.php

<?php
function add(int $a, int $b): int
{
    return $a + $b;
}
B.php

<?php
declare(strict_types=1);

require 'A.php';
var_dump(add(1.0, 2.0));
$ php B.php
PHP Fatal error:  Uncaught TypeError: Argument 1 passed to add() must be of the type integer, float given, called in /Users/hiraku/sandbox/stricttypes/B.php on line 4 and defined in /Users/hiraku/sandbox/stricttypes/A.php:2

三个文件时 declare(strict_types=1); 的作用

在函数定义部分使用 declare(strict_types=1);

再增加一个require,试试3个文件嵌套

C.php → B.php → A.php

C.php

<?php
require_once 'B.php';
var_dump(add(1.0, 2.0));
var_dump(add2(1.0, 2.0));
B.php

<?php
declare(strict_types=1);    //在函数定义部分声明
require_once 'A.php';
function add2($a, $b)
{
    return add($a, $b);
}
A.php

<?php
function add(int $a, int $b): int
{
    return $a + $b;
}

执行结果如下

$ php C.php 
int(3)
PHP Fatal error:  Uncaught TypeError: Argument 1 passed to add() must be of the type integer, float given, called in /Users/hiraku/sandbox/stricttypes/B.php on line 7 and defined in /Users/hiraku/sandbox/stricttypes/A.php:2
var_dump(add(1.0, 2.0)); 
var_dump(add2(1.0, 2.0));

也就是说, declare(strict_types=1); 会按照如下方式变化

  • 定义函数本身的文件,并不能产生效果
  • 在定义的函数中调用其它函数,严格模式能产生效果( B.php 使用了 strict_types=1 ,同时 B.php 调用了 A.php ,所以 A.php 能起作用)

在主体部分中指定strict_types

不在B.php中途位置指定strict_types,而在主要部分即C.php指定,strict模式对所有的都有效吗?然而,事实上strict模式只有在引用的地方有效

C.php → B.php → A.php

C.php

<?php
declare(strict_types=1);    //主体部分声明
require_once 'B.php';
var_dump(add2(1.0, 2.0));
B.php

<?php
require_once 'A.php';
function add2($a, $b)
{
    return add($a, $b);
}
A.php

<?php
function add(int $a, int $b): int
{
    return $a + $b;
}
$ php C.php 
int(3)
  • C.php中使用strict_types=1,因此add2(1.0,2.0)以严格模式执行,但是由于没有声明变量,所以没有任何效果
  • 另一方面,具有add2()定义的B.php处于非严格模式

总结

只有在写 declare 的文件的执行部分才会执行严格模式,该文件中调用的其它函数(其它文件中的函数)也会被影响

也就是说,哪个文件写了 declare ,哪个文件中的所有代码就需要检查,即使其中的代码来自其它文件,同时,即使这个需要检查的文件还被其它文件调用,也不改变该文件需要检查的事实

Foo.php

<?php
// 这个文件的strict有效
declare(strict_types=1);

class Foo
{
    private $bar;

    public function __construct()
    {
        $this->bar = new Bar; // 执行严格模式
    }

    public function aaa()
    {
        $this->bar->aaa(); // 执行严格模式
    }
}
Bar.php

<?php
// 这个文件strict无效
class Bar
{
    private $moo;

    public function __construct()
    {
        $this->moo = new Moo; // 执行非严格模式
    }

    public function aaa()
    {
        $this->moo->aaa(); // 执行非严格模式
    }
}

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Web Caching

Web Caching

Duane Wessels / O'Reilly Media, Inc. / 2001-6 / 39.95美元

On the World Wide Web, speed and efficiency are vital. Users have little patience for slow web pages, while network administrators want to make the most of their available bandwidth. A properly design......一起来看看 《Web Caching》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具