never 是 php 8.1 引入的底部类型,表示函数绝对不返回(必抛异常、exit 或死循环);仅适用于严格终止逻辑的函数,不可用于联合/可空类型,且继承时子类必须保持 never 声明。

never 是函数永不返回的声明类型
never 表示该函数执行后**控制流绝不会继续到下一行**——它要么抛出异常,要么调用 exit()/die(),要么陷入无限循环。这不是“可能不返回”,而是语言层面对行为的强制承诺。PHP 8.1 引入它,目的就是让类型系统能准确表达这种终止语义。
哪些函数适合声明为 never
典型场景非常具体,不是随便加的:
- 抛出异常的兜底函数,比如
fail(string $msg): never内部固定调用throw new RuntimeException($msg) - 重定向后必须终止的函数,如
redirect(string $url): never,里面必须有header()+exit - 显式退出流程的函数,例如 CLI 工具中的
abort(int $code = 1): never,只做exit($code)
注意:如果函数体里有 return、或者存在未覆盖的分支(比如 if 没写 else),PHP 会直接报错 —— never 不允许任何正常出口。
never 不能出现在联合类型或可空类型中
never 是类型理论里的“底部类型”(bottom type),它在继承中可以被任何其他返回类型替代,但反过来不行。因此它有硬性限制:
- 不能写成
int|never或?never,语法直接报错 - 父类方法声明了
never,子类重写时**必须也声明never**,否则类型不兼容(Rector 曾因忽略这点在继承链中误加never导致致命错误) - 它和
void本质不同:void表示“有返回但无值”,never表示“根本不会返回”
实际编码中最容易踩的坑
很多人看到“永不返回”就以为是“可能返回 null 或抛异常”,这是最大误解:
- 函数里写了
if ($x) { throw ...; }但没处理else分支 → 报错:Missing return statement - 用了
trigger_error()但没加exit→ 不算never,因为错误只是通知,脚本继续执行 - 在框架响应逻辑里给
render(): never加类型,但模板渲染失败时静默返回空字符串 → 类型声明与实际行为矛盾,静态分析失效
真正要用 never,得确保所有代码路径都明确终止,且工具链(如 PHPStan、Rector)能据此做更严格的推断 —— 否则不如先用文档注释说明意图。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











