PHP中如何区分类的已声明属性与动态添加属性?
PHP判断属性是否为动态添加的方法
最简便的判断方式是直接把类名作为property_exists的第一个参数进行检查:
方法1:类名作为参数调用property_exists
property_exists传入类名字符串/类常量作为第一个参数时,只会检查类定义中显式声明的属性,不会匹配实例动态添加的属性:
class Foo { public $bar; } $obj = new Foo; $obj->baz = 1; // 检查是否为类声明的属性 var_dump(property_exists(Foo::class, 'bar')); // bool(true) var_dump(property_exists(Foo::class, 'baz')); // bool(false)
注意:如果传入实例对象作为
property_exists的第一个参数,会同时匹配声明属性和动态属性,达不到区分效果。
方法2:使用反射类ReflectionClass的hasProperty方法
反射类的hasProperty方法默认只检查类定义中声明的属性,支持判断public/protected/private所有修饰符的声明属性:
$reflection = new ReflectionClass($obj); var_dump($reflection->hasProperty('bar')); // bool(true) var_dump($reflection->hasProperty('baz')); // bool(false)
方法3:对比类默认属性和实例属性差集
通过get_class_vars获取类的默认public属性列表,和get_object_vars获取的实例当前public属性列表做差集,得到的就是该实例动态添加的public属性:
$classProps = array_keys(get_class_vars(Foo::class)); $objProps = array_keys(get_object_vars($obj)); $dynamicProps = array_diff($objProps, $classProps); var_dump(in_array('bar', $dynamicProps)); // bool(false) var_dump(in_array('baz', $dynamicProps)); // bool(true)
该方法仅适用于public属性的判断,无法识别非public的声明属性。
内容的提问来源于stack exchange,提问作者Richi RM
相关产品推荐
相关产品推荐

