PHP7内核学习笔记 - 类的成员属性

  • 属性可以在定义的时候初始化,但是必须是固定值不可以是变量,也可以依赖运行时信息。比如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_tabledefault_properties_table只是存储属性的值,而属性的访问权限,属性名,静态属性值下标,非静态属性值的内存offset等,都存储zend_property_info中(即zend_class_entry->properties_info,这是一个HashTablekey就是属性名)。zend_property_info的关键成员有如下几个:
  • name:属性名,privateprotected属性会做一些特殊处理。private属性会在属性名之前加上类名protected属性会在属性名前加上*
  • offset:对于普通成员属性,此处代表内存的offset,与CV变量的操作数相同,他们分配在zend_object结构上。读取时,根据zend_object地址 + offset进行获取。对于静态成员属性,则代表default_static_members_table的数值索引,如:012
  • flag:有两个含义。一:区分属性是静态还是非静态。二:标记属性的权限,即:publicprotectedprivate

  • 使用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,子类可以为protectedpublic;如果父类是public,则子类只能为public
  • 静态属性在继承的时候,子类可以重新初始化继承来的属性的值(private属性不支持继承,但可以重新定义,级别也无所谓,三个级别都可以),但是访问权限只能被放大而不能被缩小。如父类为protected,子类可以为protectedpublic;如果父类是public,则子类只能为public,也不能遗漏static修饰符。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值