strict_types=1 必须位于 PHP 文件第一行最开头,前面不能有任何字符(包括空格、BOM、注释或代码),否则将被忽略,无法启用严格类型检查。

strict_types=1 必须放在文件最顶部,且前面不能有任何代码
它不是注释、不是配置、不是函数调用,而是一个声明指令,PHP 解析器在扫描文件时会严格检查它的位置。一旦前面有空格、BOM 字节、 之外的任何字符(包括 // 注释 或 /* */),就会直接忽略该声明,等同于没写。
常见错误现象:declare(strict_types=1) 写在 后第二行,或前面加了 IDE 自动生成的文件头注释,结果类型检查完全不生效,但又没有任何报错提示。
- ✅ 正确写法:第一行必须是
,第二行就是declare(strict_types=1); - ❌ 错误写法:前面有空行、UTF-8 BOM、注释、echo、namespace 前置语句
- ⚠️ 注意:即使
namespace也必须写在declare之后——顺序只能是→declare→namespace→ 其他
strict_types=1 不影响 require/include 的其他文件
它的作用域仅限当前文件。哪怕你在 A.php 开启了 strict_types,然后 require 'B.php',B.php 里依然按弱类型规则运行,除非 B.php 自己也写了 declare(strict_types=1)。
这意味着:类型强制不是项目级开关,而是文件粒度的显式选择。你无法靠一个入口文件“开启全局严格模式”。
- 每个需要严格类型的文件都得单独声明,不能偷懒
- 第三方库如果没写这个声明,调用它的函数时参数类型不会被强制校验
- 尤其注意 trait 和 interface 文件——它们本身不执行,但被 use 或实现时,类型检查仍取决于使用方文件是否开启 strict_types
strict_types=1 对哪些情况起作用
它只约束**函数调用时的参数类型**和**返回值类型声明**(即 PHP 7+ 的 scalar type hints 和 return type declarations),不改变变量赋值、运算符行为或数组键类型等。
例如:function foo(int $x): string { return (string)$x; } —— 调用 foo("123") 会报 TypeError;但 $a = "123"; $b = $a + 1; 依然允许,且结果是 124(字符串自动转 int)。
- ✅ 生效:函数参数、返回值、匿名函数的类型声明
- ❌ 不生效:变量赋值、数组操作、对象属性访问、
==比较、json_encode()输入等 - ⚠️ 特别注意:
declare(strict_types=1)不影响__construct()的参数类型——它只是普通方法,规则一样;但如果你用了构造函数属性提升(PHP 8.0+),类型声明同样受控
为什么有时候开了 strict_types 却没报错
最常见原因是:你调用的是内部函数(如 strlen()、array_merge())或未声明类型的用户函数。strict_types 只对带类型声明的函数起作用。
另一个隐蔽原因:你传入的是 null,而参数类型是可空的(如 ?string),或者用了联合类型(如 string|int),这些情况下也不会触发 TypeError。
- 检查目标函数是否有明确的参数/返回类型声明(比如
function bar(array $data): bool) - 确认传入值确实违反了声明(比如传
int给string参数,且非空、非联合类型) - 注意:默认值为
null的参数(如string|null $msg = null)不算可空类型声明,除非显式写成?string $msg = null
strict_types 的边界很清晰,但它依赖你主动在函数上写类型——没写的函数,再 strict 也管不到。很多人以为开了就“全面严格”,其实只是给类型声明加了一道硬校验而已。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











