PHP 8 联合类型和 PHP 7 混合类型有什么区别?
核心结论:PHP 7 根本不存在联合类型或 mixed 类型,PHP 8.0 于 2020 年 11 月正式发布后才引入联合类型(Union Types),若在未开启 declare(strict_types=1) 的情况下使用,类型检查会形同虚设,传个 bool 进 int|string 参数会静默转成 1 或''。
原因分析
PHP 7 的类型系统只支持单一类型声明(如 int、string),遇到"可能是字符串也可能是数组"这种常见场景,只能靠注释或运行时 is_array() 判断。PHP 8 允许直接写 function parseConfig(array|string $input): array|false,类型检查在解析阶段就报错,不是等到 foreach() 报 Fatal error: Uncaught TypeError 才发现。根据 2026 年 4 月 7 日的资料,联合类型不改变运行时行为,只是加了一层编译期约束;若关闭 declare(strict_types=1),弱类型转换仍会发生。
mixed 是 PHP 8.0 新增的"万能类型",但不等于 any 或省略——它明确表示"任意类型",且参与类型推导(如 array<mixed>)。如果原代码用的是 PHP 7.4 的属性类型(public string $name;),升级后遇到 null 赋值会立即报错,得改成 public ?string $name; 或初始化默认值。
解决方案
步骤一:确认 PHP 版本并启用严格模式
首先确认服务器 PHP 版本≥8.0(PHP 7 于 2015 年发布,PHP 8 于 2020 年发布)。在文件顶部添加:
<?php declare(strict_types=1);
根据 2026 年 3 月 13 日的资料,PHP 7 的弱类型函数声明在 PHP 8 下仍可跑,但一旦加了类型声明,就必须严格满足。比如 function get_id(): int 在 PHP 7 中传回 null 只警告,PHP 8 直接 Fatal error: Uncaught TypeError。
步骤二:正确书写联合类型语法
联合类型不支持空格:array | string 语法错误,必须写成 array|string。支持实用组合如 int|float|null、string|false,但不支持 array|object 这类宽泛组合。类属性也支持联合类型:public int|string $id;,但构造函数提升(Constructor Property Promotion)不支持联合类型声明。
步骤三:处理 nullable 类型的两种写法
?T 语法(如?string)等价于 string|null,二者可混用,但推荐统一用|null 风格,避免歧义。示例:
// PHP 7 风格(不推荐) public ?string $name; // PHP 8 推荐风格 public string|null $name;
注意事项
1. 命名参数不能混用位置参数在后:foo(1, name: 'x') 直接报错,必须全位置或全命名。
2. IDE(如 PHPStorm)需更新到支持 PHP 8 的版本,否则无法跳转、补全、标红错误。
3. 启用 JIT 后内存占用上升约 15–20MB,小内存容器(如 128MB 内存的云函数)可能直接 OOM。opcache.jit=1255 和 opcache.jit_buffer_size=256M 必须同时配置,否则 JIT 形同虚设。
4. json_encode 行为变了,Node.js 消费时容易解析失败,升级前需验证接口兼容性。
5. 部分扩展(如 mysql_* 函数)在 PHP 7.0 中已被移除,PHP 8.0 进一步移除了 ereg 系列函数,推荐使用 PDO 或 MySQLi 等现代扩展替代。
参考来源
来源:PHP 版本升级关键差异对比 - PHP7 和 PHP8 主要区别有哪些(2026 年 4 月 7 日)
来源:PHP 版本差异对比指南 - PHP8 和 PHP7 在语法上有什么不同(2026 年 3 月 13 日)
来源:PHP 新特性对比汇总 - PHP 版本 7 和 8 有什么区别(2026 年 3 月 11 日)
来源:PHP 版本性能对比详解 - php8.0 和 7.0 版本性能对比(2026 年 2 月 26 日)