php 8.1 引入的 never 返回类型用于声明那些永远不会正常返回值的函数,即函数执行后要么抛出异常、要么终止脚本(如调用 exit 或 die)、要么进入无限循环。定义时只需在函数签名中使用 : never 即可,编译器会强制检查所有代码路径是否确实不返回值。

never 类型的核心语义与结构

never 类型在 PHP 类型系统中是一个特殊的底部类型(bottom type),它没有实例,表示“无值”。从类型继承关系来看,never 是任何类型的子类型,这意味着它可以被赋值给任何变量类型,但反过来不行。这种设计使得类型推断更加精确,例如当函数标记为 never 时,其后的代码会被视为不可达(unreachable code)。
<?php
// 示例:使用 never 类型的错误处理函数
function abort_with_error(string $message): never {
http_response_code(500);
header('Content-Type: application/json');
echo json_encode(['error' => $message]);
exit(1); // 必须终止,否则违反 never 契约
}
// 调用者知道这里不会继续执行
abort_with_error('Database connection failed');
echo 'This line is unreachable'; // 静态分析工具会警告此行
上述代码中,abort_with_error 明确标注了 : never,表明它不会返回任何值。如果尝试在该函数中添加 return 语句而不终止程序,PHP 8.1+ 会在运行时抛出 TypeError。同时,静态分析工具(如 PHPStan 或 Psalm)能识别出后续代码不可达,从而优化或警告开发者。
修复 Core bailout 状态损坏安全问题,以及 BZ2、DOM、PDO、Opcache/JIT 内存与执行错误,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。
立即学习“PHP免费学习笔记(深入)”;
实际应用场景与最佳实践

never 类型特别适用于中间件、装饰器模式中的前置/后置检查,以及工厂方法中失败时的快速退出场景。在这些场景中,函数职责单一且明确不产生返回值,使用 never 可以增强代码的可读性和安全性。
<?php
// 中间件示例:权限检查
function require_admin(): never {
if (!isset($_SESSION['role']) || $_SESSION['role'] !== 'admin') {
http_response_code(403);
die('Access denied');
}
}
// 控制器入口
require_admin();
// 只有管理员才能到达这里
render_dashboard();
// 工厂方法示例:创建对象失败则直接终止
function create_user_from_request(array $data): never {
if (empty($data['email'])) {
throw new InvalidArgumentException('Email is required');
}
$user = new User($data);
if (!$user->save()) {
error_log('Failed to save user');
exit(1); // 终止而非返回 null
}
return $user; // 注意:这行实际上不会被执行到,因为前面已 exit
}
在第二个示例中,虽然语法上允许 return $user,但由于 never 类型要求函数不能正常返回,因此该返回语句在实际执行中永远不会被触发。更严谨的做法是移除该返回语句,或者确保所有分支都通过异常或终止来结束。使用 never 类型有助于避免潜在的逻辑漏洞,特别是在需要严格保证控制流的地方。


















