当前位置: 首页 > 后端技术 > PHP

PHP获取类私有属性的几种方式

时间:2023-03-29 14:31:07 PHP

PHP获取类私有属性的几种方法,感觉很有意思:关注推文,还有没有其他方法?经过自己的测试和网上的解答,总结出三种方法:1.反射反射可以得到一个类的详细信息。获取私有属性的值,只需要将相应属性的ReflectionProperty实例设置为可访问,然后获取该值即可。示例代码如下:

namespacetlanyan;classFoo{private$bar="Foobar!";}//获取反射类和反射属性$class=newReflectionClass(Foo::class);$property=$class->getProperty("bar");//设置属性可访问$property->setAccessible(true);$foo=newFoo;//获取对象属性值//注意:只能是通过ReflectionProperty实例的getValue方法访问//不能像这样直接访问:$foo->bar;echo$property->getValue($foo),PHP_EOL://Output:Foobar!
我写了之前的文章《PHPReflectionReview》,里面比较详细的介绍了反射和用法,有兴趣的可以阅读参考。2.转换为数组该方法用于将对象转换为数组,然后通过key获取其值。示例代码如下:
classFoo{private$bar="Foobar!";}$foo=newFoo;//强制转换$attrs=(array)$foo;//拼接键,注意“0”不能改成单引号!$键=“0”。富::类。“0”。"bar";echo$attrs[$key],PHP_EOL;//Output:Foobar!
上面代码中key的拼接比较奇葩,根据《深入理解》一文中的资料PHP原理对象(一)》,关键规则如下:对于公共属性,关键是属性名;对于受保护的属性,键是\0*\0属性名;对于私有属性,key是\0类名\0属性名。注意\0是一个字符(不是两个),对应的ASCII码是数字0,编程时用双引号括起来。不能使用单引号,否则会转义失败,即两个字符。有C语言基础的应该知道\0是字符串的结尾。这个符号直接输出不会显示,但是可以通过strlen或者ord来显示:
foreach($attrsas$key=>$value){echo"key:$key",",keylength:",strlen($key),",ascii:";对于($i=0;$i还需要注意的是,在拼接私有属性时,类名应该是“完全限定的类名”,建议通过Foo::class获取。还有一种类似于强制转换成数组的方法是serialize,但是serialize比较慢,而且序列化后的字符串更难识别和处理,所以不推荐使用。3.闭包文章开头的推特截图已经展示了闭包的用法,其中call方法是PHP7引入的,另一个是PHP5.4引入的bindTo。call和bindTo的用法示例如下:
namespacetlanyan;classFoo{private$bar="Foobar!";}$foo=newFoo;//Closure(匿名函数)是PHP5引入的函数.3$closure=function(){return$this->bar;};//PHP5.4支持bindTo方法$method=$closure->bindTo($foo,Foo::class);echo$method(),PHP_EOL;//PHP7引入了call方法,可以绑定直接执行echo$closure->call($foo),PHP_EOL;
bindTo方法的第二个参数注意是“全限定类名”传入的对象,表示函数应该放在这个类的范围内,这样它们就可以访问私有属性。性能总结:Array>Reflection>Closure易用性:Closure>Array>Reflection推荐:Closure>Reflection>ArrayReference深入理解PHP对象原理(一)访问PHP私有属性