- 属性可以在定义的时候初始化,但是必须是固定值,不可以是变量,也不可以依赖运行时信息。比如
protected $time = time();就是不合法的。
- 成员属性分为两类:静态和非静态(普通属性)。静态属性使用
::进行访问,普通属性使用->进行访问。静态属性为各个对象共享的,与常量类似。而普通属性则是各个对象独享的。与常量存储方式不同,属性并非以属性名为索引存储在HashTable中,而是通过数组保存的。静态属性保存在default_static_members_table中,以default_static_members_count表示长度;普通属性保存在default_properties_table中,以default_properties_count表示长度。
- 静态属性保存在类中,普通属性保存在对象中。静态属性保存在
zend_class_entry->default_static_members_table中,而保存在zend_class_entry->default_properties_table中的普通属性仅用于初始化对象,在对象实例化之后会被拷贝到zend_object中,也就是普通属性实际保存在对象空间内。
zend_property_info结构用于存储属性的信息。default_static_members_table和default_properties_table中只是存储属性的值,而属性的访问权限,属性名,静态属性值下标,非静态属性值的内存offset等,都存储在zend_property_info中(即zend_class_entry->properties_info,这是一个HashTable,key就是属性名)。zend_property_info的关键成员有如下几个:
name:属性名,private和protected属性会做一些特殊处理。private属性会在属性名之前加上类名,protected属性会在属性名前加上*
offset:对于普通成员属性,此处代表内存的offset,与CV变量的操作数相同,他们分配在zend_object结构上。读取时,根据zend_object地址 + offset进行获取。对于静态成员属性,则代表default_static_members_table的数值索引,如:0,1,2…
flag:有两个含义。一:区分属性是静态还是非静态。二:标记属性的权限,即:public、protected和private
- 使用
zend_property_info->offset获取属性值的时候,静态属性的值从zend_class_entry.default_static_members_table[offset]进行获取;而普通属性的值则使用((char*)zend_object) + offset来获取
- 静态属性读取步骤,以访问
self::$property_3为例:
Step1:根据字符串property_3检索properties_info,查找该属性的zend_property_info结构Step2:从zend_property_info判定该属性为静态属性Step3:以zend_property_info->offset为下标(比如说本次为0),在default_static_members_table中查找default_static_members_table[0]
- 普通属性在继承的时候,子类可以重新初始化继承来的属性的值(
private属性不支持继承,但可以重新定义,级别也无所谓,三个级别都可以),但是访问权限只能被放大而不能被缩小。如父类为protected,子类可以为protected或public;如果父类是public,则子类只能为public。
- 静态属性在继承的时候,子类可以重新初始化继承来的属性的值(
private属性不支持继承,但可以重新定义,级别也无所谓,三个级别都可以),但是访问权限只能被放大而不能被缩小。如父类为protected,子类可以为protected或public;如果父类是public,则子类只能为public,也不能遗漏static修饰符。
posted @
2019-10-05 14:36
寂地烟火
阅读(
25)
评论()
收藏
举报
来源