PHP 8.0+原生支持联合类型,用|连接多个允许类型(如int|string、string|null),运行时严格校验,错则抛TypeError;?T仅为null|T语法糖,不适用于多类型组合,void/mixed等不可参与。

int|string 这样写就对了——联合类型不是语法糖,是 PHP 8.0+ 原生支持的运行时类型检查机制,写错一个符号或混入非法类型,调用时直接抛 TypeError。
函数参数和返回值里直接用 | 连接类型
在参数、返回值、属性声明中,把多个允许的类型用竖线 | 拼起来即可,不需要额外关键字或括号:
-
function getName(int|string $id): string|null { ... }——$id可以是整数或字符串,返回值是字符串或null -
public array|object $data;—— 类属性接受数组或对象 - 类型顺序无关语义,但建议把高频类型放前面(比如
string|null比null|string更易读) - 不能写成
string | null带空格(虽然某些 IDE 不报错,但严格解析器可能失败;PHP 官方文档示例全是无空格写法)
null 必须显式写进联合类型,?T 只是简写
?string 看起来方便,但它等价于 null|string,且仅适用于“单类型 + null”这种简单情况。一旦你要组合三个及以上类型,?T 就失效了:
- ✅ 正确:
string|int|null、array|object|false - ❌ 错误:
?string|int(语法错误,?不能出现在中间) - ⚠️ 注意:
?User合法,但底层仍是User|null;如果你在 IDE 或静态分析工具里看到类型提示为User|null,别慌,这是正常展开
哪些类型能参与联合?哪些绝对不行?
PHP 8.0+ 支持的联合成员有明确范围,超出就会报编译错误(PHP Fatal error):
- ✅ 允许的:所有标量类型(
int、string、bool、float)、类名(User)、接口名(JsonSerializable)、array、iterable、callable、object、null - ❌ 禁止的:
void(任何含void的联合如int|void都非法)、mixed(它本身是伪类型,不能参与联合)、resource(虽可存在,但不推荐,因生命周期难管控) - ⚠️ 特殊注意:
self、parent、static可用,但只在类作用域内有效;脱离上下文会解析失败
运行时行为和容易踩的坑
联合类型不是装饰,PHP 解析器会在每次函数调用/赋值时做真实校验:
立即学习“PHP免费学习笔记(深入)”;
- 传入
array给声明为int|string的参数 → 立即抛Fatal error: Uncaught TypeError - 函数返回
false但声明为string|null→ 同样报错,不会自动转成null - IDE 和静态分析(如 PHPStan)依赖这个语法做推断,但它们无法代替运行时检查;你写了
string|array,不代表你可以直接调用$x->method()—— 因为string没这个方法 - 最常被忽略的一点:联合类型不改变值本身的行为。比如
int|float参数传进来是42,它还是整数,不会变成浮点;你需要自己用is_float()或gettype()做分支处理



















