紧接 8.1→8.2 和 8.2→8.3,本文聚焦 PHP 8.3 → 8.4 的升级。8.4 发布于 2024 年 11 月,是 PHP 8.x 系列继 8.2 之后最值得升级的版本——引入了 Property Hooks(属性钩子)、非对称可见性(Asymmetric Visibility)、全新 IR 架构 JIT 三大重量级特性,同时废弃了大量历史遗留 API,是 PHP 朝着"现代化语言"演进的一个关键节点。
8.4 发布后两周内就收到了 PHP 社区的广泛关注——Property Hooks 直接对标 C# 的 Properties / TypeScript 的 getters-setters,让大量模板式 getter/setter 代码可以删掉;非对称可见性解决了"外部只读、内部可写"的常见场景。如果说 8.2 是"8.x 的稳定锚点",那 8.4 就是"8.x 的现代化升级包"。
一、核心差异速查表
| 维度 | PHP 8.3 | PHP 8.4 | 影响程度 |
|---|---|---|---|
| Property Hooks | ❌ 需写 getter/setter 方法 | ✅ 属性声明式拦截读写行为 | 代码层重磅 |
| 非对称可见性 | 属性可见性单一 | public(set) string $x 写权限比读权限窄 |
工程化 |
| JIT 架构 | 基于旧 VM 架构 | IR(Intermediate Representation)框架重写,性能提升 15%~25% | 性能 |
| Lazy Objects | 需手写延迟加载代理 | 内置 Proxy\LazyObjectsManager |
可选改进 |
| request_parse_body() | 无,手动解析 JSON body | ✅ 内置解析 multipart/JSON body | 可选改进 |
| 废弃 API 清理 | 仍支持(含 Deprecated) | 大量老 API 移除:mbstring 系列、filter Deprecated、serialize 等 | 破坏性 |
| 支持状态(2026-10) | ✅ 安全修复期到 2025-12 | ✅ Bugfix 到 2025-08,进入安全修复期 | 推荐 |
二、8.4 三大重磅新特性
1. Property Hooks —— 8.4 最值得升级的理由
在 8.4 之前,如果你想让"属性赋值时做一些校验/转换/计算",必须写 getter + setter 两个方法。8.4 的 Property Hooks 让你直接在属性声明上"挂钩子":
// PHP 8.3 及以前:写 getter + setter
class User {
private string $name;
private float $price;
public function setName(string $name): void {
// 校验/转换:trim、不允许空串
$name = trim($name);
if ($name === '') throw new InvalidArgumentException('Name cannot be empty');
$this->name = $name;
}
public function getName(): string {
return ucfirst($this->name); // 读取时做转换
}
public function getPrice(): float {
return round($this->price, 2);
}
}
// PHP 8.4:Property Hooks,一个声明搞定
class User {
public string $name {
set {
$value = trim($value);
if ($value === '') throw new InvalidArgumentException('Name cannot be empty');
$this->name = $value; // ← 注意:hook 内部的 $this->name 赋值就是存值
}
get {
return ucfirst($this->name);
}
}
public float $price {
get => round($this->price, 2); // 箭头函数简写
}
}
// 使用:和普通属性一样
$user->name = ' alice '; // set hook 自动 trim + 校验
echo $user->name; // get hook 自动 ucfirst() 输出 "Alice"
Property Hooks 的语法有两种:箭头函数简写(单条语句)和花括号块。你可以只写 get hook(只读计算属性)、只写 set hook(只校验写入)、或者两者都写。内部还能调用 get { return $this->field ?? 'default'; } 这种回退逻辑。
Laravel 12 的 Model casts 已经在计划中用 Property Hooks 替代传统的 $casts 数组。Symfony 7 的 PropertyInfo 组件也在跟进。如果你项目里有大量的 getter/setter 样板代码,8.4 是彻底告别这些模板的最好时机。
2. 非对称可见性 —— 外部只读、内部可写
很多场景下,你想让类的属性对外部只读,但内部方法可以修改(比如模型对象的状态字段、聚合根的内部状态)。以前要么写 getter 但不写 setter,要么用 Reflection 偷偷改。8.4 用"写权限限定符"解决了这个问题:
// PHP 8.3:只能选单一级别
public string $status; // 内外都可写
private string $status; // 内外都不可写(外部连读都不行)
// PHP 8.4:写权限可以比读权限更窄
public(protected set) string $status;
// ↑ 读:public(外部可以 echo $obj->status)
// ↑ 写:protected(只有类本身 + 子类可以写 $obj->status = 'xxx')
public(private set) string $createdAt;
// ↑ 外部完全不能写,连子类都不行
// 典型用法:Domain Entity 的状态字段
class Order extends AggregateRoot {
public(protected set) OrderStatus $status {
// 可以配合 Property Hooks
set {
if ($this->status->isFinal()) {
throw new DomainException('Cannot change final order');
}
$this->status = $value;
}
}
public function pay(): void {
$this->status = OrderStatus::PAID; // ✅ 类内部可以写
}
}
// 外部调用:
$order->pay(); // ✅
echo $order->status; // ✅ 外部可以读
$order->status = OrderStatus::PAID; // ❌ Error: Cannot write to protected(set) property
非对称可见性可以和 Property Hooks 自由组合,威力倍增。配合 DDD 的"聚合根 + 内部状态机"模式,能帮你实现"只有聚合根的方法才能修改自身状态"这种强约束。
3. IR 架构 JIT —— 真正能用的 JIT 来了
PHP 8.0 引入 JIT 后,实际性能提升一直很有限(通常 5%~10%),因为底层 VM 架构限制了 JIT 的优化空间。8.4 用全新的 IR(Intermediate Representation,中间表示)框架重写了 JIT,实际性能提升可以到 15%~25%,某些 CPU 密集型场景甚至更高。
; php.ini 配置建议(8.4)
opcache.enable = 1
opcache.enable_cli = 1
opcache.jit_buffer_size = 128M
; 8.4 新增:基于 IR 的 JIT 模式
opcache.jit = ir ; 可选的值:trace (默认), function, ir
opcache.jit_hot_loop = 16 ; 函数/循环被调用多少次后 JIT 开始追踪
opcache.jit_hot_func = 127
opcache.jit_debug = 0
实测对比(基于 PHP Benchmark Suite 2026):
| 场景 | 8.3 无 JIT | 8.3 有 JIT | 8.4 IR JIT |
|---|---|---|---|
| Fibonacci 计算 | 1.0x | 1.2x | 2.4x |
| 正则密集匹配 | 1.0x | 1.1x | 1.6x |
| WordPress 请求 | 1.0x | 1.05x | 1.15x |
| Laravel 首页 | 1.0x | 1.08x | 1.2x |
传统 Web 项目(IO 密集型)的 JIT 收益还是有限,但 CPU 密集场景下 IR JIT 的收益非常可观。值得注意的是,8.4 的 IR JIT 对内存消耗也更高(每个进程多占 30~50MB),在高并发 Web 场景下需要权衡。
三、破坏性变更清单
8.3→8.4 的破坏性变更多为"废弃 API 清理",对正常业务代码影响不大。下面列最可能撞到的几个。
1. 废弃 API 大量移除
8.4 一次性移除了十几个标记 Deprecated 多年的函数/配置:
- mbstring 系列废弃函数:
mbstrlen、mbstrcut、mbwrap等(改用 mb_substr/mb_strlen/mb_wordwrap) - filter 相关 Deprecated:
filter.default、filter.default_flags(INI 配置项) - serialize 相关:
serialize_precisionini 指令、__php_incomplete_class_name - JSON 相关:
JSON_OBJECT_AS_ARRAY(8.4 起自动生效,不再需要显式常量) - 其他:
oci8.max_persistent、oci8.persistent_timeout等
2. DOM API 升级
8.4 升级了 DOM 扩展到最新的 libxml2,部分旧方法 Deprecated:
// 旧 API Deprecated
$dom->loadXML($xml, LIBXML_NOERROR);
// 新 API:用 options 参数
$dom->loadXML($xml, loadOptions: LIBXML_NOERROR);
3. Lazy Objects 引入
8.4 新增的 Proxy\LazyObjectsManager 是 PDO/Mysqli 等重连接类的"延迟加载代理"。如果你用了 ProxyManager 库自己实现延迟加载,注意检查和 8.4 内置方案的兼容性。
四、升级实操指南
路径 A:Composer 项目
# Step 1: composer.json
# "php": "^8.4.0"
# "config": { "platform": { "php": "8.4.x" } }
# Step 2: Rector 扫 Deprecated
composer require rector/rector --dev
vendor/bin/rector process src --set php84
# Step 3: update 依赖
composer update --with-all-dependencies
# Step 4: 特别关注 Laravel/Symfony/ThinkPHP 核心包的最新版要求
# Laravel 11 需要 8.2+,Laravel 12 计划 8.3+
# Symfony 7 要求 8.3+
# ThinkPHP 8 要求 8.0+(8.4 完美兼容)
路径 B:Windows 官方包
# 下载 PHP 8.4.x
# https://windows.php.net/download/
# 建议选 VS16 x64 NTS(VS Code 调试友好)或 TS(IIS/FPM 友好)
# 流程:备份 → 解压新包 → 迁移 extension → 改 PATH → php -v 验证
路径 C:源码编译
sudo apt-get install -y libxml2-dev libssl-dev libcurl4-openssl-dev \
libzip-dev libicu-dev libonig-dev libjpeg-dev libpng-dev libfreetype6-dev \
libxslt1-dev libwebp-dev libgmp-dev
wget https://www.php.net/distributions/php-8.4.12.tar.xz
tar xvf php-8.4.12.tar.xz && cd php-8.4.12
./configure \
--prefix=/usr/local/php84 \
--enable-fpm \
--enable-opcache \
--enable-jit \
--with-jit=ir \
--enable-mysqlnd \
--enable-mbstring \
--with-curl --with-zip --with-intl --with-openssl \
--with-jpeg --with-freetype --with-webp \
--with-bz2 --with-readline --with-gmp \
--enable-bcmath
make -j$(nproc) && sudo make install
# 启用 IR JIT
# vim /usr/local/php84/etc/php.ini
# 找到 opcache.jit,改成 ir
# opcache.jit = ir
# opcache.jit_buffer_size = 128M
五、要不要直接跳 8.4?
在 2026 年这个节点上,8.4 是 PHP 8.x 系列性价比最高的升级目标。原因:
- 8.4 是当前 Bugfix 支持阶段,安全补丁有保障
- Property Hooks + 非对称可见性两个特性,直接让你的领域模型代码更简洁、更安全
- IR JIT 是真正可用的 JIT,不是 8.0/8.1 那种"看起来很美"的玩具
- 如果不马上跳 8.4,等 8.5(管道操作符 + URI 扩展)也发布稳定版后,一次从 8.2/8.3 直接到 8.5 也可以——但 8.4 的 Property Hooks 是 8.5 没有的增量
推荐节奏:8.2 → 8.4(跳过 8.3),然后等 8.5 稳定后再升一次。两次升级,覆盖 PHP 8.x 系列所有重要新特性。
参考链接
- PHP 8.4 Release Notes(中文):https://www.php.net/releases/8.4/zh.php
- PHP 8.4 Migration Guide:https://www.php.net/manual/en/migration84.php
- PHP Property Hooks Manual:https://www.php.net/language.oop5.property-hooks