declare(strict_types=1)仅对当前文件直接定义的函数调用生效,不继承至require/include的文件,也不约束变量赋值或运算,仅强化已声明参数类型的检查。

strict_types=1 只影响当前文件,不会继承到 require 的文件里
PHP 的 declare(strict_types=1) 是文件级开关,只对当前文件中**直接定义的函数调用**生效,不穿透到 require、include 或类方法内部调用的其他文件。很多人误以为加了它整个项目就“全严格”了,结果在被引入的文件里传 float 给 int 参数却没报错——那是因为那个文件自己没声明 strict_types=1。
常见错误现象:TypeError: Argument 1 passed to foo() must be of the type int, float given 只在当前文件调用时触发,如果 foo() 定义在另一个没声明 strict_types 的文件里,哪怕你传 float 进去也不会报错(默认弱类型转换)。
- 必须在文件顶部(BOM 之后、任何语句之前)写
declare(strict_types=1); - 它不影响返回类型声明(
function f(): int本身就有运行时检查) - 它只约束「函数调用时的参数类型」,不约束变量赋值或运算过程
int 和 integer、float 和 double 在 strict_types 下等价,但写法要统一
PHP 类型别名在类型声明中是互通的,int ≡ integer,float ≡ double,bool ≡ boolean,string 没别名。但实际编码中建议全程用短名(int、float),因为 PHP 8+ 的反射和错误信息都优先显示短名,混用容易在 IDE 提示或调试时造成困惑。
例如:你写 function sum(int $a, integer $b): int,虽然合法,但调用时 sum(1.5, 2) 会报错,且错误信息里显示的是 int,不是 integer,容易让人误判哪一参出问题。
立即学习“PHP免费学习笔记(深入)”;
-
array和Array不等价 —— 后者不是有效类型,会 Parse Error -
callable和string|array|object等联合类型需 PHP 8.0+,且 strict_types 对联合类型只校验是否匹配任一成员,不自动转换 - 标量类型声明(
int、string等)在 strict_types=1 下拒绝隐式转换,比如(string)123→"123"是显式转换,允许;但strlen(42)会直接报错
第三方库调用不受你的 strict_types 控制,得看它自己有没有声明
你自己的文件开了 strict_types=1,但调用 vendor/autoload.php 或某个 Composer 包里的函数(比如 Carbon::parse()),是否报类型错,完全取决于那个函数定义所在的文件有没有 declare(strict_types=1)。大多数主流库(如 Laravel、Symfony)为了兼容性,默认不启用 strict_types,所以你传 string 给它期待 int 的参数,大概率被静默转成 0 或空字符串,而不是报错。
这意味着:strict_types 是“防御性工具”,不是“类型安全保险”。它只帮你守住你自己写的函数边界,拦不住外部输入或依赖行为。
- 想验证某函数是否受 strict_types 约束?看它的源码文件开头有没有
declare(strict_types=1) - 可以用
php -l filename.php快速检查语法,但无法静态判断 strict_types 是否生效 —— 必须运行时触发调用 - 单元测试里开启 strict_types 后,mock 对象传参也要注意类型匹配,否则
$mock->method('foo')->with($this->equalTo(42))可能因整数/浮点差异失败
strict_types=1 和类型声明语法不是一回事,别漏写冒号
新手常把 declare(strict_types=1) 当成“让所有变量都严格”的开关,结果写了它,却忘了在函数上加类型声明,比如:
declare(strict_types=1);
function add($a, $b) { return $a + $b; }
add("1", "2"); // 不报错!因为参数没声明类型,strict_types 对它无效
strict_types 只增强已声明类型的检查力度,不自动给没声明的参数加约束。它和类型声明是配合关系,不是替代关系。
- 参数类型声明(
function f(int $x))和返回类型声明(function f(): int)必须显式写出,strict_types 才有作用对象 - 类属性类型(PHP 7.4+)和 const 类型(PHP 8.2+)不受 strict_types 影响,它们有自己的检查规则
- 闭包也支持类型声明:
$fn = function(int $x): string { return (string)$x; };,此时 strict_types 同样生效



















