php 7.0+ 返回值类型检查始终强制生效,与 strict_types=1 无关;后者仅约束参数类型。void 禁止显式返回值,?type 需手动判空,匿名函数类型声明位置须正确。

PHP 7.0 的函数类型声明不是“开了就稳”,关键在 strict_types 的作用范围和返回值校验的独立性——它只管参数,不管返回值;而返回值类型检查永远强制生效,且不受 declare(strict_types=1) 控制。
strict_types=1 只影响参数,不影响返回值校验
很多人误以为开了 declare(strict_types=1) 就能“统一管住所有类型”,其实它只约束函数调用时传入参数的类型匹配。返回值类型检查是另一套机制,无论 strict_types 开没开,只要写了 : int 这类声明,运行时就强制执行。
- 如果函数声明了
: int,但实际 return "42"(字符串),会直接抛出TypeError,哪怕没写declare(strict_types=1) - 如果没声明返回类型,返回 "42" 或 42 都没问题;一旦声明,就必须严格符合——包括 null 也不能偷偷溜进
: string函数里 -
declare(strict_types=1)必须是文件第一行(允许前导空白),否则无效;它对其他文件完全没影响
void 返回类型最容易踩的坑:return 后不能跟值
void 不是“随便返回啥都行”,而是“明确禁止返回任何表达式”。哪怕 return null; 或 return; 都合法,但 return "done"; 或 return true; 会立刻报错。
- 常见错误:把原本有返回值的函数改成
: void,却忘了删掉旧的return $result;语句 - 隐式返回
null是允许的(即函数末尾无 return),但显式写return;更清晰 - 别用
: void来“占位”或“以后再加返回值”——它意味着你确定这个函数纯粹是副作用操作(如日志、DB 写入)
可空返回类型 ?Type 要配合 null 检查,不能只靠声明
?User 这类可空类型从 PHP 7.1 开始支持,但它只是告诉 PHP “可以返回 User 实例或 null”,并不自动帮你做 if ($user === null) 判断。
- 如果函数声明为
function find(int $id): ?User,调用后必须自己检查返回值是否为null,否则后续调用$user->getName()会触发Call to a member function ... on null -
?int和int|null等价,但后者是 PHP 8.0+ 才支持的联合类型写法;PHP 7.1–7.4 只认?前缀形式 - 不要混用:
function foo(): ?string与function foo(): string是完全不同的契约,调用方必须按声明处理
匿名函数传参时,类型声明要写在变量定义处,不是调用时
匿名函数也能用标量类型声明,但语法位置容易错——类型必须写在 function 关键字后的参数列表里,而不是赋值给变量的时候。
- 正确写法:
$add = function(int $a, int $b): int { return $a + $b; }; - 错误写法:
$add: callable(int, int): int = function($a, $b) { ... };——PHP 不支持这种变量级类型注解 - 如果启用
strict_types=1,调用$add("1", "2")会报错;不启用则可能静默转成整数,结果不可靠 - 匿名函数的类型声明和具名函数一样,返回值校验同样强制,
: void同样禁止带值 return
最常被忽略的一点:返回值类型检查发生在函数执行**结束瞬间**,不是编译期。这意味着即使你用了 declare(strict_types=1),也拦不住一个在函数体内先改了变量类型、最后又 return 错类型的操作——错误只在 return 那一刻爆发。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











