PHP 8.4 新特性详解:属性钩子、非对称可见性与更多
PHP 8.4 于 2024 年 11 月正式发布,带来了期待已久的「属性钩子」特性,以及多项语法糖和性能改进。如果你还在用 PHP 8.2 或更早版本,本文帮你快速掌握升级的理由。
一、属性钩子(Property Hooks)⭐ 重磅特性
这是 PHP 8.4 最受期待的特性,允许在属性的 get/set 上直接定义逻辑,无需编写 getter/setter 方法。
之前的写法
php
class User
{
private string $_email = '';
public function getEmail(): string
{
return strtolower($this->_email);
}
public function setEmail(string $value): void
{
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException("邮箱格式不正确");
}
$this->_email = $value;
}
}PHP 8.4 写法
php
class User
{
public string $email {
get => strtolower($this->email);
set {
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException("邮箱格式不正确");
}
$this->email = $value;
}
}
}
$user = new User();
$user->email = "Zhang@Example.COM";
echo $user->email; // zhang@example.com只读虚拟属性
php
class Circle
{
public function __construct(public float $radius) {}
// 只有 get,没有 set(只读虚拟属性)
public float $area {
get => M_PI * $this->radius ** 2;
}
public float $diameter {
get => $this->radius * 2;
set => $this->radius = $value / 2;
}
}
$c = new Circle(5.0);
echo $c->area; // 78.53981...
echo $c->diameter; // 10
$c->diameter = 20;
echo $c->radius; // 10二、非对称可见性(Asymmetric Visibility)
可以为属性的读和写分别设置不同的访问级别。
php
class User
{
// public 读,private 写(只有类内部才能修改)
public private(set) int $id;
// public 读,protected 写
public protected(set) string $name;
// 构造器提升也支持
public function __construct(
public private(set) string $email,
public readonly string $createdAt = ''
) {}
}
$user = new User('zhang@example.com');
echo $user->id; // ✅ 可读
$user->id = 1; // ❌ 报错:不能在类外部写入三、new 表达式不加括号直接调用方法
php
// PHP 8.3 及之前:必须加括号
$result = (new MyClass())->method();
// PHP 8.4:可以直接调用
$result = new MyClass()->method();
// 可以链式调用
$value = new QueryBuilder()
->select('id', 'name')
->from('users')
->where('active', 1)
->limit(10)
->get();四、新增数组函数
array_find() / array_find_key()
php
$users = [
['id' => 1, 'name' => '张三', 'role' => 'admin'],
['id' => 2, 'name' => '李四', 'role' => 'user'],
['id' => 3, 'name' => '王五', 'role' => 'admin'],
];
// 找到第一个满足条件的元素
$admin = array_find($users, fn($u) => $u['role'] === 'admin');
// ['id' => 1, 'name' => '张三', 'role' => 'admin']
// 找到第一个满足条件的 key
$key = array_find_key($users, fn($u) => $u['name'] === '李四');
// 1
// 检查是否有元素满足条件
$hasAdmin = array_any($users, fn($u) => $u['role'] === 'admin'); // true
// 检查是否所有元素都满足条件
$allActive = array_all($users, fn($u) => isset($u['id'])); // true五、HTML5 解析支持
php
// 新增 Dom\HTMLDocument(支持 HTML5 解析)
$doc = Dom\HTMLDocument::createFromString('
<html>
<body>
<h1>Hello PHP 8.4</h1>
<p class="intro">新特性介绍</p>
</body>
</html>
');
$h1 = $doc->querySelector('h1');
echo $h1->textContent; // Hello PHP 8.4
$paras = $doc->querySelectorAll('p.intro');
foreach ($paras as $p) {
echo $p->textContent;
}六、#[\Deprecated] 弃用属性
php
class LegacyAPI
{
#[\Deprecated(
message: "请使用 newMethod() 代替",
since: "2.0"
)]
public function oldMethod(): void
{
// ...
}
public function newMethod(): void
{
// ...
}
}
$api = new LegacyAPI();
$api->oldMethod();
// Deprecated: LegacyAPI::oldMethod() is deprecated since 2.0, 请使用 newMethod() 代替七、JIT 编译器改进
PHP 8.4 对 JIT(即时编译器)进行了重大重构,简化了配置:
ini
; PHP 8.3 及之前的复杂配置
opcache.enable=1
opcache.jit_buffer_size=64M
opcache.jit=1255
; PHP 8.4 简化配置
opcache.enable=1
opcache.jit_buffer_size=64M
opcache.jit=on ; 直接用 on/off 即可八、其他改进
懒对象(Lazy Objects)
php
// 懒初始化:只在首次访问时才真正创建对象
$reflector = new ReflectionClass(MyHeavyService::class);
$service = $reflector->newLazyGhost(function(MyHeavyService $obj): void {
$obj->__construct(/* 昂贵的初始化 */);
});
// 此时 $service 还未真正初始化
// 首次访问属性时才触发初始化
echo $service->someProperty; // 触发初始化BCMath 对象 API
php
use BcMath\Number;
$a = new Number('10.5');
$b = new Number('3.2');
$result = $a + $b; // 使用运算符直接计算
echo $result; // 13.7
$result = ($a * $b)->round(2);
echo $result; // 33.6九、升级注意事项
PHP 8.4 的破坏性变更:
php
// 1. implode() 参数顺序弃用
implode($array, $separator); // ❌ 弃用(旧顺序)
implode($separator, $array); // ✅ 正确
// 2. 某些 HTML 实体编码函数的默认编码改为 UTF-8
htmlspecialchars($str); // 默认编码变为 ENT_QUOTES | ENT_SUBSTITUTE
// 3. GMP 对象不再可序列化
$n = gmp_init('12345');
serialize($n); // ❌ 报错总结
| 特性 | 重要程度 | 说明 |
|---|---|---|
| 属性钩子 | ⭐⭐⭐ | 彻底改变属性封装方式 |
| 非对称可见性 | ⭐⭐⭐ | 精细控制读写权限 |
| new 不加括号 | ⭐⭐ | 语法糖,链式调用更流畅 |
| array_find 等 | ⭐⭐ | 减少手写循环 |
| HTML5 解析 | ⭐⭐ | 告别 DOMDocument 的痛苦 |
| JIT 简化配置 | ⭐ | 对普通开发者透明 |
PHP 8.4 的属性钩子是该版本最大的亮点,它让 PHP 的 OOP 更现代,代码更简洁。建议生产环境在 PHP 8.4.1+ 后升级。
作者:PFinal南丞 | 更新时间:2026-04-21

