never类型函数绝不可能正常返回,合法终止方式包括抛异常、exit/die和无限循环;任何return语句或未覆盖所有分支的条件逻辑均违反其语义。

程序会立即终止当前函数的执行流程,控制权交还给调用方的上一层作用域——但不会“继续往下走”,因为 never 类型本身意味着该函数**绝不可能正常返回**。
never 函数抛异常后的实际行为
当一个声明为 never 的函数内部抛出异常(如 throw new RuntimeException()),PHP 会按常规异常机制处理:中断当前函数、展开栈、寻找匹配的 catch 块。这完全合法,也是 never 允许的三大终止方式之一(另两种是 exit()/die() 和无限循环)。
关键点在于:只要函数没“成功返回值”,就没违背 never 的语义。
常见合法写法示例
-
直接抛异常:
function abort(string $msg): never { throw new InvalidArgumentException($msg); } -
条件抛异常:
function requireAdmin(User $user): never { if (!$user->isAdmin()) { throw new PermissionDeniedException(); } }(注意:此写法需确保所有分支都终止,否则会报错) -
组合 exit + throw:
function handleFatalError(): never { error_log('Critical failure'); exit(1); }
容易踩的坑
以下写法会导致 PHPStan 报 return.never 错误或运行时逻辑矛盾:
立即学习“PHP免费学习笔记(深入)”;
- 在
never函数里写了return;或return null;—— 这等于“我终止了,但又正常返回”,语义冲突 - 有
if分支只抛异常,但缺少else分支处理其他情况,导致部分路径可能“漏掉终止” - 调用了另一个可能返回的函数(比如未标注
never的辅助函数),而没做兜底终止
和 void 的本质区别
void 表示“可以返回,只是不返回有意义的值”,允许 return;;never 表示“根本走不到 return 那一步”,任何 return 都是错误。所以即使你抛了异常,只要没写 return,就完全合规。



















