You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP 8.1+中创建只读属性的引用为何触发修改错误?

<?php

declare(strict_types=1);

class Example {
    public readonly array $setOne;
    public readonly array $setTwo;

    public function __construct()
    {
        // Populate $setOne and $setTwo with a lot of data
    }

    public function doThing()
    {
        $map = [
            'one' => &$this->setOne,
            'two' => &$this->setTwo,
        ];

        // Loop over the Map and evaluate the data
        // Take action on the data, but don't try to change it
    }
}

在PHP >=8.1版本中,尝试创建readonly属性的引用时,会触发错误:Fatal error: Uncaught Error: Cannot modify readonly property。若执行unset($map['one'][0]);这类修改操作触发该错误是合理的,但仅创建引用就报错,请问为何PHP会将创建引用视为修改操作?

原因解析

PHP的readonly属性核心设计目标是确保属性在初始化完成后,无法被重新赋值或间接修改。创建引用的行为之所以被判定为“修改操作”,本质是因为它打破了readonly属性的安全边界:

  • 引用直接关联到属性的底层值容器(zval),相当于给readonly属性开了一个不受赋值限制的“后门”。哪怕你当前没打算修改,后续任何通过引用对值的操作(比如重新赋值、修改数组元素)都会直接篡改readonly属性的内容,完全违背readonly的设计初衷。
  • PHP采取的是预防性拦截策略:与其等到后续真的发生修改再报错,不如从源头禁止创建引用的行为,彻底杜绝readonly属性被篡改的可能性。

举个简单的例子,如果允许创建引用,后续哪怕误写$map['one'] = [];,就会直接覆盖readonly属性的原有值,这显然不符合readonly属性的定义。PHP选择在创建引用时就触发错误,是为了从根源上消除这种潜在风险。

内容的提问来源于stack exchange,提问作者Tyler V.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 05:37:08