
PHP 8.0 引入的可空类型语法允许在类型前加 ?,明确声明该参数、属性或返回值可接受对应类型或 null,提升类型安全性和代码可读性。
php 8.0 引入的可空类型语法允许在类型前加 `?`,明确声明该参数、属性或返回值可接受对应类型或 `null`,提升类型安全性和代码可读性。
在 PHP 面向对象编程中,你可能会遇到如下构造函数签名:
class Service
{
private Logger $logger;
public function __construct(
?Logger $logger = null,
) {
$this->logger = $logger ?? new NullLogger();
}
}
这里的 ?Logger 并非注释或运算符,而是 可空类型声明(Nullable Type Declaration) —— 它告诉 PHP 解释器:该参数 $logger 的合法值既可以是 Logger 类型的实例,也可以是 null。
✅ 语法规则与要点
- ? 必须紧贴类型名左侧,中间不可有空格:?Logger ✅,? Logger ❌(语法错误);
- 可空类型仅适用于类名、接口名、内置标量类型(如 ?string、?int)及 ?array、?object 等,但不支持 ?self、?parent 或泛型占位符(PHP 8.3+ 支持有限泛型,但 ?T 仍非法);
- 若声明了 ?Type,则默认值建议显式设为 null(如 = null),否则调用时若省略参数,会因类型不匹配而报 TypeError;
- 启用严格模式(declare(strict_types=1);)时,可空类型检查更严格,但 ?Type 本身即属严格类型系统一部分,无需额外开启。
? 实际调用示例
// 合法调用
new Service(new FileLogger()); // ✅ 传入 Logger 子类实例
new Service(null); // ✅ 显式传 null
new Service(); // ✅ 使用默认值 null(因声明了 = null)
// 非法调用(运行时报 TypeError)
new Service("invalid"); // ❌ string 不符合 ?Logger
new Service(42); // ❌ int 不符合 ?Logger
⚠️ 注意事项
- 可空类型 不是联合类型替代品:?Logger 等价于 Logger|null,但二者语法地位不同——前者是独立语法糖,后者是 PHP 8.0+ 的显式联合类型(需写成 Logger|null)。两者效果一致,但 ?Logger 更简洁,且向后兼容性更好(PHP 7.1+ 即支持);
- 不可对 ?null、?void 或 ??Type 等形式使用,会触发解析错误;
- 在 PHPStan、Psalm 等静态分析工具中,?Type 能被精准识别,显著提升类型推断准确性与错误捕获能力。
? 总结
? 是 PHP 类型系统的“空安全开关”:它让开发者以声明式方式表达“此处允许缺失”,既避免冗余的 @var 注解,又强化运行时类型保障。结合空合并操作符(??)与空安全调用(?->),可构建出健壮、自文档化且易于维护的现代 PHP 应用架构。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











