php7内核剖析,PHP7内核剖析8之 类

本文深入探讨了PHP7的内核结构,特别是类的实现,包括zend_class_entry结构体,详细阐述了类的类型、属性、静态属性、方法和常量的存储方式。此外,还介绍了对象的数据结构,包括属性和方法的访问以及对象的创建过程。
摘要由CSDN通过智能技术生成

本篇文章的内容介绍的是关于PHP7内核剖析8之 类 ,现在分享给大家,有需要的朋友可以参考一下

1.类的结构类是编译阶段的产物,编译完成后我们定义的每个类都会生成一个zend_class_entry,它保存着类的全部信息,在执行阶段所有类相关的操作都是用的这个结构struct _zend_class_entry {

char type; //类的类型:内部类ZEND_INTERNAL_CLASS(1)、用户自定义类ZEND_USER_CLASS(2)

zend_string *name; //类名,PHP类不区分大小写,统一为小写

struct _zend_class_entry *parent; //父类

int refcount;

uint32_t ce_flags; //类掩码,如普通类、抽象类、接口,

int default_properties_count; //普通属性数,包括public、private

int default_static_members_count; //静态属性数,static

zval *default_properties_table; //普通属性值数组

zval *default_static_members_table; //静态属性值数组

zval *static_members_table;

HashTable function_table; //成员方法哈希表

HashTable properties_info; //成员属性基本信息哈希表,key为成员名,value为zend_property_info

HashTable constants_table; //常量哈希表,通过constant定义的

//以下是构造函授、析构函数、魔术方法的指针

union _zend_function *constructor;

union _zend_function *destructor;

union _zend_function *clone;

union _zend_function *__get;

union _zend_function *__set;

union _zend_function *__unset;

union _zend_function *__isset;

union _zend_function *__call;

union _zend_function *__callstatic;

union _zend_function *__tostring;

union _zend_function *__debugInfo;

union _zend_function *serialize_func;

union _zend_function *unserialize_func;

}

2.类常量PHP中可以把在类中始终保持不变的值定义为常量,在定义和使用常量的时候不需要使用 $ 符号,常量的值必须是一个定值,它们通过zend_class_entry.constants_table进行存储,这是一个哈希结构常量的读取:

class my_class {

const A1 = "hi";

}

echo my_class::A1;

编译到echo my_class::A1这行时首先会尝试检索下是否已经编译了my_class,如果能在CG(class_table)中找到,则进一步从类的contants_table查找对应的常量,找到的话则会复制其value替换常量,简单的讲就是类似C语言中的宏,编译时替换为实际的值了,而不是在运行时再去检索。

echo my_class::A1;

class my_class {

const A1 = "hi";

}

在运行时再去检索。替换成为实际的值

3.成员属性属性中的变量可以初始化,但是初始化的值必须是常数,这里的常数是指PHP脚本在编译阶段时就可以得到其值,而不依赖于运行时的信息才能求值,比如public $time = time();这样定义一个属性就会触发语法错误。

成员属性又分为两类:普通属性、静态属性,与常量的存储方式不同,成员属性的初始化值并不是直接用以"属性名"作为索引的哈希表存储的,而是通过数组保存的

595edf287eabbaeed7431622d9feb768.png实际只是成员属性的VALUE通过数组存储的,访问时仍然是根据以"属性名"为索引的散列表查找具体VALUE的,而这个散列表是zend_class_entry.properties_infotypedef struct _zend_property_info {

uint32_t offset; //普通成员变量的内存偏移值,静态成员变量的数组索引

uint32_t flags; //属性掩码,如public、private、protected及是否为静态属性

zend_string *name; //属性名:并不是原始属性名,private会在原始属性名前加上类名,protected则会加上*作为前缀

zend_string *doc_comment;

zend_class_entry *ce; //所属类

} zend_property_info;

4.成员方法每个类可以定义若干属于本类的函数(称之为成员方法),这种函数与普通的function相同,只是以类的维度进行管理,不是全局性的,所以成员方法保存在类中而不是EG(function_table)

c6e0535cd3644d1f65e76e56539b13ea.png成员方法也有静态、非静态之分,静态方法中不能使用$this,因为其操作的作用域全部都是类的而不是对象的,而非静态方法中可以通过$this访问属于本对象的成员属性

5.对象的数据结构typedef struct _zend_object zend_object;

struct _zend_object {

zend_refcounted_h gc; //引用计数

uint32_t handle; //对象编号

zend_class_entry *ce; //所属类

const zend_object_handlers *handlers; //对象操作处理函数

HashTable *properties; //普通成员属性哈希表

zval properties_table[1]; //普通属性值数组

};对象的创建:首先是根据类名在EG(class_table)中查找对应zend_class_entry、然后是创建并初始化一个对象、最后是初始化调用构造函数的zend_execute_data

相关推荐:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值