php 7.0 返回值类型声明强制校验且与 strict_types 无关;declare(strict_types=1) 必须位于文件首行非空非注释位置,仅作用于当前文件,参数类型检查受其控制,返回值检查则无条件生效。

PHP 7.0 的函数类型声明不是“开了 strict_types 就万事大吉”,它只管参数,不管返回值;而返回值校验是独立、强制、无条件生效的。
declare(strict_types=1) 必须放在文件第一行,且只对当前文件生效
很多人把 declare(strict_types=1) 写在注释后面、namespace 后面,甚至写在函数定义之后——这些都会让声明完全失效,PHP 当作没看见。
常见错误现象:multiply("3", "4") 居然没报错,还以为 strict 模式起作用了,其实是根本没启用。
- 必须是文件中第一个非空白、非注释的语句(允许前导空格和
//或/* */注释) - 不能跨文件继承:A.php 开了 strict,require B.php,B.php 里依然按弱模式运行
- Composer 加载的类文件也各自独立判断,不会受入口文件影响
: int 这类返回类型声明,运行时强制校验,和 strict_types 无关
只要函数签名写了 : int,哪怕整个项目都没写过 declare(strict_types=1),一旦 return "42",立刻抛出 TypeError。
容易踩的坑:
- 把旧函数加了
: string,但忘了清理内部可能返回null或数组的分支 - 用
json_decode($json, true)后直接return $data['name'] ?? '',结果$data是false,返回false→ 触发TypeError: Return value must be of type string -
: void函数里写了return "done";,不是警告,是致命错误
?Type 可空类型不等于自动判空,调用方必须自己检查
function find_user(int $id): ?User 声明后,PHP 只保证返回 User 实例或 null,但不会帮你拦截 null 后续调用。
典型崩溃场景:
-
$user = find_user(999); $user->getName();→Fatal error: Call to a member function getName() on null - 误以为
?int和int|null是等价写法:后者是 PHP 8.0+ 才支持的联合类型,PHP 7.1–7.4 只认?int - 在严格模式下传
null给参数function handle(?string $msg)是合法的;但若参数是string $msg,传null就会报错(strict 下)或静默转成空字符串(弱模式)
匿名函数的类型声明必须写在 function() 括号内,不是变量赋值处
正确写法:$filter = function(array $items, callable $cb): array { ... };
错误写法:$filter: callable = function($items, $cb) { ... };(PHP 会直接报语法错误)
关键点:
- 类型声明位置和普通函数一致:参数列表后、
{前 - 不能在变量名后加类型(那是 PHP 8.0+ 的属性/变量类型,不适用于匿名函数赋值)
- 闭包绑定
use ($x)的变量不参与类型声明,它们的类型由外部作用域决定
最常被忽略的一点:返回值类型检查永远强制,哪怕你删掉所有 declare(strict_types=1),只要写了 : Type,PHP 就会在函数退出那一刻做硬校验——这不是可选行为,是语言层铁律。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











