紧接 7.4→8.0、8.0→8.1、8.1→8.2,本文聚焦 PHP 8.2 → 8.3 的升级。8.3 发布于 2023 年 11 月,是 PHP 8.x 系列中最"温和"的升级——官方定性为"主要是修复和清理,新特性增量有限"。如果你刚从 8.1 升到 8.2 完成了"大折腾",8.2→8.3 是一次"放松式"升级。
8.3 的三大新特性——类型化类常量(Typed Class Constants)、Override Attribute、Trait 方法可见性改进——都是对语言既有能力的"补齐",没有像 8.1 枚举、8.2 readonly class 那样的范式级更新。破坏性变更几乎只有一个:strftime() 彻底移除(8.1 就 Deprecated,8.3 才动手)。
一、核心差异速查表
| 维度 | PHP 8.2 | PHP 8.3 | 影响程度 |
|---|---|---|---|
| 类型化类常量 | ❌ 不支持 | ✅ 可以声明类型:const string X = 'foo' |
可选改进 |
| #[\Override] | ❌ 无 | ✅ 标记重写方法,编译器检查签名 | 工程化 |
| Trait 方法可见性 | 需用 insteadof/as 语法 | 可以直接在 trait 内部声明可见性 | 可选改进 |
| JSON 类常量 | 硬编码字符串 | ✅ JSON::parse() 等类常量 |
可选改进 |
| strftime() | Deprecated | ❌ 彻底移除,用 IntlDateFormatter | 破坏性 |
| 日期/时间精度 | 微秒级字符串 | DateInterval 支持微秒和纳秒 | 可选改进 |
| 性能 | — | 内部优化约 3%,新的 JIT buffer 管理 | 性能 |
| 支持状态(2026-10) | ❌ 完全 EOL | ✅ 仍在安全修复窗口(2024-11 进入安全修复期) | 安全 |
二、8.3 三大新特性
1. 类型化类常量(Typed Class Constants)
这是 8.3 最直接的代码层改进——给类常量声明类型,编译器会帮你检查类型约束:
// PHP 8.2 及以前
class HttpStatus {
const OK = 200; // 没类型,默认 int
const NOT_FOUND = 404;
const DEFAULT_MSG = 'OK'; // 跟整数混在一起,全靠人记忆
}
// PHP 8.3:类型化
class HttpStatus {
const int OK = 200;
const int NOT_FOUND = 404;
const string DEFAULT_MSG = 'OK';
const array CACHE_TTL = ['short' => 60, 'long' => 3600];
}
// 编译器会检查赋值是否匹配
const int WRONG = 'abc'; // ❌ Fatal: Type mismatch
这个特性对大型项目的常量管理非常有价值——尤其当常量数量多、跨模块共享时,类型声明就是自带文档。
2. #[\Override] Attribute
类似 Java 的 @Override 注解,PHP 8.3 引入 Override Attribute 让编译器帮你确认"这个方法确实是在重写父类/接口的方法":
abstract class Animal {
public function speak(): string {
return '...';
}
}
class Dog extends Animal {
// 8.2 及以前:没有检查,如果父类后来改了方法名,子类会悄悄留下死代码
// 8.3:加 Override,编译器验证
public function speak(): string {
return 'Woof!';
}
// 写错父类方法名:
#[Override]
public function speack(): string { // ❌ Error: Method Dog::speack() does not override
return '...'; // any method from parent Animal
}
}
// 8.3 的 Override 也支持接口
interface JsonSerializable {
public function jsonSerialize(): mixed;
}
class MyModel implements JsonSerializable {
#[Override]
public function jsonSerialize(): mixed { /* ... */ }
}
这个 Attribute 的真正价值是防御父类重构:当父类改了方法名或签名,你在子类里加了 #[Override] 的方法会直接报 Fatal Error,而不是默默留下一个永远不被调用的"幽灵方法"。
3. Trait 方法可见性改进
以前 Trait 的方法可见性只能在 use 处修改(as 语法),8.3 允许直接在 Trait 内部声明:
// PHP 8.2 及以前
trait Logger {
public function log(string $msg) { /* ... */ }
}
class Service {
use Logger {
log as private; // 只能在 use 处用 as 改可见性
}
}
// PHP 8.3:直接在 trait 里声明
trait Logger {
private function logInternal(string $msg) { /* ... */ }
}
class Service {
use Logger;
// 不需要 as 语法了,trait 内部的可见性直接生效
}
这个改进让 Trait 的封装性更好——Trait 可以"自带"方法可见性声明,而不是把可见性暴露给使用方去决定。
三、破坏性变更:基本只有 strftime()
8.2→8.3 的破坏性变更极少,大部分项目可以"零改动升级"。最主要的一个:
strftime() 彻底移除
从 8.1 就开始 Deprecated,8.3 终于动手:
// PHP 8.3 直接 Fatal Error
strftime('%Y-%m-%d', time());
// 替换方案:
// 方案 A:IntlDateFormatter(推荐,国际化支持好)
$formatter = new IntlDateFormatter('zh_CN', IntlDateFormatter::LONG, IntlDateFormatter::NONE);
echo $formatter->format(new DateTime());
// 方案 B:用 date() 或 DateTime::format()(简单场景)
date('Y-m-d');
(new DateTime())->format('Y-m-d');
// 方案 C:用 IntlCalendar(需要更复杂的日历操作)
其他零散的 Deprecated:ini_get('date.default_latitude') 等天文计算相关的 ini 配置被标记 Deprecated(影响极小)。
四、升级实操指南
# Composer 项目
# 1. composer.json: "php": "^8.3.0"
# config.platform.php 改为 8.3.x
# 2. 直接 update(不需要跑 Rector php83——破坏性变更极少)
composer update --with-all-dependencies
# Windows 官方包:https://windows.php.net/download/
# 流程不变:下载 → 解压 → 改 PATH → 迁移扩展 → 验证
# 源码编译
wget https://www.php.net/distributions/php-8.3.31.tar.xz
tar xvf php-8.3.31.tar.xz && cd php-8.3.31
./configure --prefix=/usr/local/php83 --enable-fpm --enable-opcache --enable-jit --enable-mysqlnd --enable-mbstring --with-curl --with-zip --with-intl --with-openssl
make -j$(nproc) && sudo make install
五、8.2→8.3 vs 8.1→8.2 难度对比
| 对比维度 | 8.1 → 8.2 | 8.2 → 8.3 |
|---|---|---|
| 破坏性变更数量 | 5+(动态属性 Error、preg /e、utf8_encode Deprecated、null 独立类型、strftime Deprecated) | 1(strftime 移除) |
| 代码改动量 | 3%~10% | 0%~1%(如果没用 strftime 就是 0) |
| Rector 需求 | 必须跑 php82 规则 | 可选(扫一下 Deprecated 即可) |
| 升级时间(中小项目) | 30 分钟 ~ 半天 | 5 分钟 ~ 30 分钟 |
六、要不要升 8.3?还是直接跳 8.4?
在 2026 年这个节点上,8.3 的增量特性吸引力确实有限。类型化常量、Override、Trait 可见性——这些特性"锦上添花但不雪中送炭"。如果你项目代码里不用 strftime,那 8.2→8.3 的升级几乎可以无感完成。
但有一点值得注意:8.3 是 PHP 目前仍在安全修复窗口内的最低版本(8.2 已经完全 EOL)。如果你的项目还在 8.2,至少应该升到 8.3 以获得安全补丁。
推荐节奏:8.2 → 8.3(5 分钟搞定)→ 攒一波 → 8.4(Property Hooks 是 8.4 才有的硬货)。跳过 8.3 的话安全上不太划算——毕竟只差一次 composer update 的事。
参考链接
- PHP 8.3 Release Notes:https://www.php.net/releases/8.3/
- PHP 8.3 Migration Guide:https://www.php.net/manual/en/migration83.php