声明 PHP 文件作为严格模式的一个好事是,实际上只适用于当前文件。这确保了这个文件是严格类型,但是他没有影响到整个项目中的其他文件。这允许你一步一步的迁移非严格模式的代码。
使用提示类型没有 strict_types 可能导致微妙的错误。
严格类型之前,int x 意味着 x must have a value coercible to an int。
设置严格模式后,you tell the engine that int x means x must only be an int proper, no type coercion allowed。
谁给更关心 strict_type
这行?is more for the reader than for the writer. Why? Bacause it will explicitly tell the reader:
The types in this current scope are treated strictly.
<?php
function add(int $a, int $b): int
{
return $a + $b;
}
var_dump(add(1.0, 2.0));
运行输出 int(3)
。
<?php
declare(strict_types=1);
function add(int $a, int $b): int
{
return $a + $b;
}
var_dump(add(1.0, 2.0));
运行输出:
PHP Fatal error: Uncaught TypeError: Argument 1 passed to add() must be of the type int, float given, ...
必须在脚本最前。不能写在脚本的中间,如下写法是错误的:
<?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 ...
不得使用 block mode 进行声明:
<?php
declare(strict_types=1) {
var_dump(1);
}
运行后报错:
PHP Fatal error: strict_types declaration must not use block mode in ...
A.php
<?php
// 严格模式
declare(strict_types=1);
function add(int $a, int $b): int
{
return $a + $b;
}
B.php
<?php
// 非严格模式
require 'A.php';
// 违反了 A 的定义
var_dump(add(1.0, 2.0));
运行
php B.php
int(3)
A.php
<?php
// 非严格模式
function add(int $a, int $b): int
{
return $a + $b;
}
B.php
<?php
// 严格模式
declare(strict_types=1);
require 'A.php';
// 违反了 A 的定义
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 int, float given, called in ...
declare(strict_types=1);
的声明本身在 A.php 文件中完成。被 B.php 文件 require,而 B.php 并没有定义严格模式,那么执行 require 的 B.php 文件不会变成严格模式。只有在写 declare 的文件的执行部分才会执行严格模式,该文件中调用的其它函数(其它文件中的函数)也会被影响。
若果想完全使用严格模式,比较简单的方法是在所有 php 文件都写上 declare(strict_types=1);
。
推荐自动格式化工具:symplify/easy-coding-standard。
– EOF –