在鸟哥《深入理解PHP原理之对象(一)》看到一段挺有意思的代码
“PHP通过这种比较ugly但是简单高效的方法, 实现了对属性访问权限的标识.知道了, 我们就可以干一些不合常理的事请, 比如访问对象的私有/保护属性”
至于这算不算BUG本文就不议论了,有兴趣的可以看看这里 (见: Bug #44273 access to private and protected class variables allowed when casting to array ): 下面有相关议论
那为什么对象转成数组以后能通过构建特殊的key去访问呢?直接看关键代码吧! (已下代码PHP版本为: 5.4.27)
可以看到当属性是private和protected时候调用zend_mangle_property_name
来构造property_info.name
(转换后的key),而它们第3,4个参数也不一样,private传入的是类名
,而protected传入的是*
字符。在看看zend_mangle_property_name
函数的实现就一目了然了。
所以对象的private属性我们可以强制转换为array后通过$obj["\0类名\0属性名"]
来访问,而protected则是$obj["\0*\0属性名"]
至于流程可以通过zend_do_declare_property
关键字到 http://lxr.php.net/ 搜索, 大概就是
- zend_do_declare_property
- zend_declare_property_ex
- zend_mangle_property_name
嗯,好像也没写什么的样子,一些细节比如property_info被zend_hash_quick_update, 类型的转换都没理解清楚。