PHP 8.0联合类型仅支持函数参数、返回值和静态变量声明三处,语法为type1|type2(无空格、大小写敏感、不可含void或重复类型),类属性/const/局部变量/catch块均不支持。

PHP 8.0 的联合类型不是“想在哪写就在哪写”,写错位置直接 ParseError,根本跑不起来。能用联合类型的只有三处:函数参数、返回值、静态变量声明——其他地方写即报错,没商量。
函数参数和返回值声明必须用 | 分隔,且不能含 void 或重复类型
这是最常踩坑的位置。联合类型语法是 type1|type2|type3,中间不能有空格,也不能混入非法类型。
-
void不允许出现在联合类型中(string|void→ ParseError) -
null必须显式写出(string|null✅,但string默认不允许null❌) - 等价写法
?string是string|null的语法糖,两者都合法,但别混用逻辑(比如参数用?int,返回值却写int|null,虽不报错,但易引发团队理解偏差) - 类型名大小写敏感:
Int|String❌(必须小写int|string),类名除外(User|Admin✅) - 别写
int|integer或bool|boolean—— 这是重复类型,PHP 会直接拒绝解析
类属性、局部变量、const 声明里写联合类型必报错
很多人从 TypeScript 或 PHPDoc 注释习惯迁移到 PHP 8.0,下意识在属性上写 private string|int $id;,结果一运行就崩:
-
ParseError: Syntax error, unexpected '|'—— 这是因为类属性(public/protected/private)**完全不支持**联合类型 - 同理,
const、global变量、普通函数体内的局部变量(如$x: string|int;)也都不支持 - 如果真需要多类型属性,只能退回到
mixed+ 文档注释,或用 getter/setter 手动校验 - catch 块也不行:
catch (InvalidArgumentException|RuntimeException $e)看似像联合类型,其实是语法糖,底层仍是单类型匹配机制,不是真正的联合类型校验
静态变量声明要小心“首次赋值锁定类型分支”
这是最容易被忽略的运行时陷阱。静态变量支持联合类型,但它的类型不是“每次都能变”,而是首次执行时根据初始值锁定可接受的分支:
立即学习“PHP免费学习笔记(深入)”;
-
static int|string $count = 0;✅(0匹配int,后续赋值必须是int或string) - 但如果第一次调用时写成
static int|string $count = 'init';,那后续就不能再赋42以外的int?不对——它只锁定“该变量当前已满足的联合分支”,后续仍可赋任一分支值,只要符合声明;真正限制在于:**一旦某次赋值触发了类型不匹配,就立刻TypeError** - 常见误操作:
static array|string $data = [];✅,但之后写$data = new DateTime();❌(DateTime不在array|string中) - 注意:静态变量初始化表达式本身必须至少满足一个分支,否则解析阶段就失败(如
static int|string $x = true;→ ParseError)
最危险的不是语法写错,而是误以为联合类型能“自动转换”或“宽松兼容”。PHP 运行时对每个传入参数、每个 return 表达式都做硬性校验,不妥协。哪怕你写了 int|float,传个 '123' 字符串也会炸——它不会帮你转成 int,也不会静默收为 float。



















