strict_types=1必须每文件手动声明且置于首行非空白非注释位置,仅对当前文件函数参数与返回值类型校验生效,不影响变量赋值或跨文件调用;函数、属性类型声明需显式写出,可空类型统一用?type,联合类型仍要求精确匹配。

PHP 类型声明不是“写了就严格”,必须配合明确的语义规则和文件级配置才能真正起效。核心要求集中在三处:函数参数与返回值、类属性、以及strict_types=1 的声明位置与作用域。
函数参数与返回值必须显式标注类型
PHP 7.0+ 支持在函数定义中声明参数和返回值类型,例如 function find(int $id): User。这不仅是文档提示,更是运行时校验依据:
- 参数类型不匹配时,是否报错取决于该函数所在文件是否启用
declare(strict_types=1);未启用则尝试隐式转换(如 "123" → 1),启用则直接抛TypeError - 返回值类型检查同样受
strict_types控制:函数体末尾return "abc"给声明为: int的函数,会触发错误 - 可空类型统一用
?Type写法(如?string),string|null仅在 PHP 8.0+ 是合法联合类型,但语义等价,推荐优先使用?Type保持简洁 - 联合类型(如
int|string|null)不改变 strict 模式逻辑——传入 "5" 给int|null依然失败,因为它既不是int也不是null
类属性需带访问修饰符且类型声明即约束
PHP 8.0+ 强制所有属性声明必须包含 public、protected 或 private,否则解析失败。类型声明在此处是语法强制项:
-
public int $id;要求该属性在读取前已被赋值,否则触发Uninitialized property错误 - 可空属性必须显式写成
public ?string $email;,不能依赖弱模式兜底;赋值null合法,赋值false或0则报错 - 默认值必须与声明类型一致:
public string $status = 'pending';合法,= null或= 0直接语法错误 -
readonly属性(PHP 8.2+)只能在构造函数中赋值一次,之后不可修改,包括反射也无法绕过
strict_types=1 必须每文件手动声明且位置精准
这个指令不是全局开关,而是每个 PHP 文件的独立契约:
- 必须位于文件**第一行非空白、非注释、无 BOM、无空行的位置**,紧接
<?php标签,例如:<?php declare(strict_types=1); - 它只对当前文件中定义的函数生效,
include或require进来的其他文件仍按自身是否声明决定模式 - Laravel、Symfony 等主流框架的源码基本未启用该声明,所以你在控制器里加了它,调用
$request->integer('limit')仍可能返回null或字符串,不会自动转成int - CI 流程建议用 Git hook 或 PHP-CS-Fixer 自动检查所有
.php文件首行是否匹配正则^<?php \s+declare\(strict_types=1\);
局部变量只能靠 PHPDoc 做静态分析提示
PHP 解析器不支持 string $name = 'foo'; 这类写法,但可通过 PHPDoc 辅助工具识别:
- 格式为
/** @var string $message */,且必须紧挨变量声明上一行 - 数组结构可细化描述,如
/** @var array<int array int msg: string> $data */</int> - 避免使用
@var mixed或@var object,静态分析工具基本无法推导 - 这类注释不影响运行时,但 PHPStan、Psalm、IDE 补全都依赖它
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











