严格模式(declare(strict_types=1);)禁止参数隐式类型转换,传入非预期类型直接抛TypeError;默认强制模式则自动转换。该声明必须位于文件首行非注释非空白处,仅作用于当前文件,不影响返回值类型检查。

严格模式(declare(strict_types=1);)和强制模式(默认行为)的区别,本质是「类型是否允许隐式转换」——启用严格模式后,int 就必须是 int,"5" 传给 int $x 参数会直接抛出 TypeError;不启用则 PHP 会悄悄转成 5,表面跑通,实则埋雷。
strict_types=1 必须写在文件最开头
这个声明不是可选配置,也不是全局开关,它只对当前文件生效,且必须是脚本中第一个非空白、非注释的语句:
- ✅ 正确:
declare(strict_types=1);在第 1 行(前面最多允许空格或//注释) - ❌ 错误:放在
namespace后、函数内、或任何require/include之后 - ❌ 错误:写成
declare(strict_types = 1);(等号两边有空格)——虽然 PHP 通常容忍,但部分旧版本或严格 linter 会警告 - ⚠️ 注意:即使你
require了一个启用了strict_types=1的文件,也不会影响当前文件——每个文件独立判断
参数类型不匹配时的行为差异
同一个函数,在两种模式下对相同输入的反应可能完全不同:
- 函数定义:
function sum(int $a, int $b): int { return $a + $b; } - 调用
sum("10", "20"):- 强制模式(默认):成功返回
30,PHP 把字符串自动转为整数 - 严格模式(
strict_types=1):立即抛出Fatal error: Uncaught TypeError
- 强制模式(默认):成功返回
- 调用
sum(null, 5):- 强制模式:转成
0,返回5 - 严格模式:直接报错,
null不是int
- 强制模式:转成
- 布尔值也一样:
sum(true, false)在强制模式下变成1 + 0 = 1,严格模式下直接挂掉
返回值类型声明不受 strict_types 影响
strict_types 只控制「参数传入时」的类型检查逻辑,而返回值类型(如 : int)无论是否启用严格模式,都会强制执行——只要函数实际返回了非 int 值,就会报错。
立即学习“PHP免费学习笔记(深入)”;
- 例如:
function getAge(): int { return "25"; }- 不管有没有
declare(strict_types=1);,运行时都抛出TypeError
- 不管有没有
- 但注意:如果函数里写了
return "25" + 0;,PHP 会在返回前尝试转成整数,这属于表达式求值行为,不是strict_types控制的范围 - 真正受
strict_types约束的,只有「调用时传参」这一环节
最容易被忽略的是:团队协作时,有人忘了加 declare(strict_types=1);,结果同一套接口在不同文件里表现不一致——参数有时能松散传,有时突然崩。这不是 PHP 的 bug,而是设计使然:它把控制权交还给开发者,但要求你清楚每一行代码落在哪种模式下。



















