PHP类使用未定义属性:添加__set()后为何出现未定义属性通知?
为什么添加__set()方法后PHP类无法正确返回属性值?
这是个很典型的PHP魔术方法使用误区,我来给你讲明白背后的原因:
先看第一个能正常输出8的代码:
<?php class a{ public function out(){ $this->test = 8; return $this->test; } } $b = new a(); echo $b->out(); ?>
这段代码里,当你执行$this->test = 8时,因为类a里没有预先定义test这个属性,PHP会自动给当前对象动态添加一个公共属性,后续读取$this->test时自然能拿到8,所以运行结果正常。
但当你给类加上空的__set()魔术方法后,逻辑就完全变了:
<?php class a{ public function __set($property, $value) { } public function out(){ $this->test = 8; return $this->test; } } $b = new a(); echo $b->out(); ?>
这里的核心规则是:只要类中定义了__set()方法,PHP就不会再自动为对象动态创建未声明的属性。
具体拆解一下流程:
- 当你给未定义的属性
$this->test赋值时,PHP会直接触发你写的__set()方法,把属性名test和值8传递进去。但你的__set()是空实现——既没有给对象添加这个属性,也没有把值存储到任何地方。 - 之后你尝试读取
$this->test时,这个属性根本不存在,所以PHP就抛出了Undefined property: a::$test的通知,自然也拿不到预期的8。
如果想让代码恢复正常,你需要在__set()里手动处理属性的存储,比如用一个私有数组来保存动态属性,同时配套__get()方法来读取:
<?php class a{ private $dynamicProps = []; public function __set($property, $value) { $this->dynamicProps[$property] = $value; } public function __get($property) { return $this->dynamicProps[$property] ?? null; } public function out(){ $this->test = 8; return $this->test; } } $b = new a(); echo $b->out(); // 现在会正常输出8 ?>
这样赋值时__set()把值存入数组,读取时__get()从数组中取出,就能得到预期的结果了。
内容的提问来源于stack exchange,提问作者Deqin Chen
相关产品推荐
相关产品推荐

