strict_types=1强制函数参数类型精确匹配,禁止隐式转换;仅对当前文件直接定义调用的函数生效,须置于首行,值为1或0,不约束返回值、属性赋值及伪类型。

strict_types=1 会阻止字符串数字被悄悄转成 int
它最直接的作用,就是让 add(int $a, int $b) 这类函数拒绝接收 "123" 这样的字符串参数。默认模式下 PHP 会自动把它转成整数 123 并继续执行;开启后,只要类型不完全匹配(string ≠ int),就立刻抛出 TypeError,而不是等运行到逻辑深处才出错。
- 常见错误现象:传入 JSON 解析后的字段(如
$_POST['id'])是字符串,函数却声明了int $id,结果在宽松模式下“看似正常”,实则丢失精度或触发边界异常 - 注意:只对当前文件中「直接定义并调用」的函数生效,
require进来的函数不受影响,必须在那个文件也加declare(strict_types=1); - 浮点数同理:
add(1.5, 2.7)在 strict 模式下也会报错,因为float不等于int,不会被截断
strict_types=1 不管返回值、属性、数组键这些事
它只检查函数调用时传进去的参数类型,其他地方照旧松散:
-
function getAge(): int { return "25"; }—— 返回字符串但声明了int,strict_types=1 完全不管,照样静默转成25 -
$user->name = 123;—— 类属性赋值不校验类型,哪怕public string $name;也拦不住 -
$arr["1"]和$arr[1]在数组访问时仍可能混用,strict_types 不干预索引类型转换 - 伪类型如
mixed、iterable、array不受 strict_types 约束,传什么都过
strict_types=1 必须放在文件最顶上,差一行都不行
这个声明极其挑剔位置:
- 必须紧跟在
<?php后面,前面不能有空行、BOM、注释(除了 PHPDoc 风格的文档块,但稳妥起见建议啥都别放) - 如果文件开头是
namespace App\Model;,那declare得写在 namespace 前面,否则直接解析失败 - ThinkPHP 8 模型里若漏掉或位置错,会导致属性赋值失败却静默存
0或空字符串,而不是报错 - 值只能是
1(开)或0(关),写declare(strict_types=true)会报语法错误
strict_types=1 不是银弹,得配合其他手段才真正安全
它只是堵住函数参数这一条路,但漏洞还在别处冒头:
立即学习“PHP免费学习笔记(深入)”;
- 动态数组访问没做
isset()或array_key_exists()检查,照样引发 Notice 或逻辑错 - 用了
array类型提示,但实际传入的是stdClass对象,strict_types 不拦 - 返回类型靠
: int声明,但没人强制你 return 的真是 int —— PHP 8 的ReturnTypeWillChange注解也只起提醒作用 - 真要提升类型可靠性,得配静态分析工具(如 PHPStan level 5+)和 IDE 类型推导,单靠 strict_types=1 远不够
最容易被忽略的一点:团队协作时,有人忘了在新写的工具类里加这行,或者 IDE 模板没配置好,就会导致同一项目里部分文件严格、部分宽松,契约瞬间断裂——这种不一致比全宽松更危险。



















