PHP中readonly修饰符能否替代protected getter方法?
PHP 8.1的readonly私有属性能否替代protected getter方法?
在PHP 8.1版本之前,子类要获取父类的私有属性,主要有两种实现方式:
方式一:私有属性+Protected Getter方法
父类定义私有属性,同时提供protected的getter方法供子类调用,既保证属性不被外部随意修改,又让子类能安全获取值:
abstract class Base { private $thing; public function __construct($thing) { $this->thing = $thing; } protected function getThing() { return $this->thing; } } class Test1 extends Base { private function needThing() { // 通过getter获取属性值 ... $this->getThing(); } } class Test2 extends Base { private function needThing() { ... $this->getThing(); } }
方式二:直接使用Protected属性
将属性设为protected,子类可以直接访问,但缺点是属性能被子类随意修改,安全性不足:
abstract class Base { protected $thing; public function __construct($thing) { $this->thing = $thing; } } class Test1 extends Base { private function needThing() { // 直接访问属性 ... $this->thing; } } class Test2 extends Base { private function needThing() { ... $this->thing; } }
PHP 8.1的readonly私有属性方案
PHP 8.1引入readonly修饰符后,我们可以定义readonly私有属性:子类能直接访问属性值,同时无法修改它,兼顾了便捷性和安全性:
abstract class Base { readonly private $thing; public function __construct($thing) { $this->thing = $thing; } // 这里的getter方法看起来显得多余 protected function getThing() { return $this->thing; } } class Test1 extends Base { private function needThing() { // 直接访问readonly私有属性 ... $this->thing; } } class Test2 extends Base { private function needThing() { ... $this->thing; } }
结论:readonly私有属性不能完全替代protected getter
虽然readonly私有属性在很多场景下可以简化代码,但它并不能完全替代protected getter方法,具体差异如下:
适合用readonly替代的场景
当属性是不可变的简单值,且不需要对返回值做任何加工时,readonly私有属性可以直接替代getter,代码更简洁直观。
仍需要使用getter的场景
- 需要加工返回值:如果要在返回属性前做格式化、类型转换或计算衍生值,getter可以封装这些逻辑,子类无需关注内部实现细节。
- 未来可能修改属性实现:如果后续属性的存储方式改变(比如从直接存储改为从数据库/缓存获取),使用getter的话子类代码无需修改;直接访问readonly属性的话,所有子类都要调整。
- 兼容旧版本PHP:如果项目需要支持PHP 8.1以下的版本,readonly修饰符无法使用,必须依赖getter。
- 统一代码规范:部分团队坚持使用getter统一访问属性的风格,即使readonly能用,也会继续保持这种规范来维持代码一致性。
内容的提问来源于stack exchange,提问作者John Smith
相关产品推荐
相关产品推荐

