首页 > 后端开发 > php教程 > 聊聊有关declare(strict_types=1)的有效范围

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

藏色散人
发布: 2023-04-10 21:28:01
转载
7155 人浏览过

本文给大家介绍关于关于declare(strict_types=1)的有效范围,希望对需要的朋友有所帮助!

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

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

单个文件时strict_types应写在哪里

基本语法

1

2

3

4

5

6

7

<?php

function add(int $a, int $b): int

{

    return $a + $b;

}

 

var_dump(add(1.0, 2.0));

登录后复制

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

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

做了如下变更

1

2

3

4

5

6

7

8

9

<?php

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

 

function add(int $a, int $b): int

{

    return $a + $b;

}

 

var_dump(add(1.0, 2.0));

登录后复制

TypeError产生,如下

1

2

3

4

5

6

7

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语法不能写在脚本的中间,如下写法是错误的

1

2

3

4

5

6

7

8

9

<?php

function add(int $a, int $b): int

{

    return $a + $b;

}

 

declare(strict_types=1);

 

var_dump(add(1.0, 2.0));

登录后复制

产生如下错误

1

2

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,而是编译过程中产生的错误

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

1

2

3

4

<?php

declare(strict_types=1) {

  //...

}

登录后复制

1

2

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脚本在开头声明严格模式

1

2

3

4

5

6

7

8

A.php脚本

 

<?php

declare(strict_types=1);

function add(int $a, int $b): int

{

    return $a + $b;

}

登录后复制

A.phpB.php文件require,如下

1

2

3

4

5

B.php脚本

 

<?php

require &#39;A.php&#39;;

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

登录后复制

执行结果

1

2

$ 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使用严格模式

1

2

3

4

5

6

7

A.php

 

<?php

function add(int $a, int $b): int

{

    return $a + $b;

}

登录后复制
登录后复制
登录后复制

1

2

3

4

5

6

7

B.php

 

<?php

declare(strict_types=1);

 

require &#39;A.php&#39;;

var_dump(add(1.0, 2.0));

登录后复制

1

2

3

4

$ 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

1

2

3

4

5

6

C.php

 

<?php

require_once &#39;B.php&#39;;

var_dump(add(1.0, 2.0));

var_dump(add2(1.0, 2.0));

登录后复制

1

2

3

4

5

6

7

8

9

B.php

 

<?php

declare(strict_types=1);    //在函数定义部分声明

require_once &#39;A.php&#39;;

function add2($a, $b)

{

    return add($a, $b);

}

登录后复制

1

2

3

4

5

6

7

A.php

 

<?php

function add(int $a, int $b): int

{

    return $a + $b;

}

登录后复制
登录后复制
登录后复制

执行结果如下

1

2

3

4

5

$ 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));产生TypeError错误

也就是说,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

1

2

3

4

5

6

C.php

 

<?php

declare(strict_types=1);    //主体部分声明

require_once &#39;B.php&#39;;

var_dump(add2(1.0, 2.0));

登录后复制

1

2

3

4

5

6

7

8

B.php

 

<?php

require_once &#39;A.php&#39;;

function add2($a, $b)

{

    return add($a, $b);

}

登录后复制

1

2

3

4

5

6

7

A.php

 

<?php

function add(int $a, int $b): int

{

    return $a + $b;

}

登录后复制
登录后复制
登录后复制

1

2

$ php C.php

int(3)

登录后复制
  • C.php中使用strict_types=1,因此add2(1.0,2.0)以严格模式执行,但是由于没有声明变量,所以没有任何效果
  • 另一方面,具有add2()定义的B.php处于非严格模式

总结

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

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

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(); // 执行严格模式

    }

}

登录后复制

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

Bar.php

 

<?php

// 这个文件strict无效

class Bar

{

    private $moo;

 

    public function __construct()

    {

        $this->moo = new Moo; // 执行非严格模式

    }

 

    public function aaa()

    {

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

    }

}

登录后复制

推荐学习:《PHP视频教程

以上是聊聊有关declare(strict_types=1)的有效范围的详细内容。更多信息请关注PHP中文网其他相关文章!

相关标签:
php
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
怎么学好php
来自于 1970-01-01 08:00:00
0
0
0
PHP扩展intl
来自于 1970-01-01 08:00:00
0
0
0
php数据获取?
来自于 1970-01-01 08:00:00
0
0
0
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板