PHP魔术方法与empty()函数的异常行为问题咨询
为什么empty()在这个PHP场景中返回true?
你的代码运行后出现了看似矛盾的结果:
var_dump($data->example)能正确输出字符串'1234',说明__get方法可以正常返回值var_dump($data->example == null)输出false,证明值确实不为null- 但
var_dump(empty($data->example))却返回true,核心原因在于PHP的empty()函数对对象属性的判断逻辑:
关键逻辑解析
当访问对象的未定义成员属性时:
- 因为你定义了
__set方法,PHP会认为该属性是「可动态设置」的,但实际上你只是把值存在了$testData数组里,并没有真正给对象实例添加这个成员属性 empty()判断时会先检查对象本身是否存在该属性——显然不存在,此时如果没有定义__isset方法,empty()会直接返回true,完全不会触发__get方法
而当你移除__set后,PHP会判定该属性不可动态设置,此时empty()会触发__get方法,拿到返回的'1234',自然判断为非空,结果符合预期。
解决办法
给类添加__isset方法,让它检查$testData数组中是否存在对应键,就能让empty()正确判断:
class testData { protected $testData = []; public function __construct($dane = []) { if (is_array($dane)) { $this->testData = $dane; } } public function __get($xKey) { if (array_key_exists($xKey, $this->testData)) { return $this->testData[$xKey]; } return null; } public function __set($xKey, $xValue) { $this->testData[$xKey] = $xValue; } // 添加__isset方法 public function __isset($xKey) { return array_key_exists($xKey, $this->testData); } }
添加后,empty($data->example)会先调用__isset('example')得到true,接着触发__get拿到值,最终判断为非空,输出false。
总结
empty()对对象属性的判断优先级:
- 优先检查属性是否直接存在于对象实例中
- 不存在时,若有
__isset则调用它,根据返回值决定是否调用__get - 有
__set但无__isset时,默认判定属性「可设置但实际不存在」,直接返回true - 既无
__isset也无__set时,触发__get,根据返回值判断
内容的提问来源于stack exchange,提问作者Stepel
相关产品推荐
相关产品推荐

