PHP 8.2 的 readonly class 要求属性不可重复声明 readonly、必须在构造函数中显式初始化、禁用动态属性和 static 成员,并强制继承链中子类也需声明为 readonly。

PHP 8.1 的 readonly 属性和 PHP 8.2 新增的 readonly class 语法本身不冲突,但升级后若代码中混用旧写法与新语义,或未注意约束变化,就容易触发解析错误或运行时异常。关键不是“语法冲突”,而是**语义升级带来的隐式限制增强**,需针对性调整。
检查并移除属性级 readonly 修饰符
在 PHP 8.2 中,若已将类声明为 readonly,再给属性单独加 readonly 会报错:Cannot use "readonly" on property in readonly class。
- ❌ 错误写法(PHP 8.2 不允许):
public readonly string $name;
}
- ✅ 正确写法(属性自动只读,无需重复声明):
public string $name;
}
确保所有属性都在构造函数中初始化
PHP 8.2 的只读类要求:每个属性必须在构造函数中显式赋值(通过参数提升或体内赋值),不能留空、不能靠默认值、也不能延迟初始化。
- ❌ 不合法(缺少初始化):
public string $host;
public int $port;
public function __construct() {} // 未赋值!
}
- ✅ 推荐写法(参数提升,简洁明确):
public function __construct(
public string $host,
public int $port
) {}
}
禁用动态属性与 static 成员
只读类自动禁止 #[\AllowDynamicProperties] 和 static 属性——这两项在 PHP 8.1 的单个 readonly 属性中是允许的,升级后需清理。
修复 Core bailout 状态损坏安全问题,以及 BZ2、DOM、PDO、Opcache/JIT 内存与执行错误,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。
立即学习“PHP免费学习笔记(深入)”;
- ❌ 以下写法在只读类中直接报错:
#[\AllowDynamicProperties] // Parse error
public string $id;
public static int $version = 1; // Parse error
}
- ✅ 替代方案:
如需动态字段,改用明确声明的数组属性(如 public array $metadata);静态常量仍可用(public const VERSION = '2.0';)。
继承关系需显式对齐只读状态
PHP 8.2 明确禁止非只读类继承只读类,但允许只读类继承普通父类。若原有代码存在 class Admin extends User 且 User 升级为 readonly class,子类必须同步声明为 readonly,否则报致命错误。
- ✅ 允许:
readonly class User extends BaseUser { /* OK */ }
readonly class Admin extends User { /* OK,子类也显式 readonly */ }
- ❌ 禁止:
class Admin extends User { } // Fatal error: Cannot extend readonly class


















