PHP7内核剖析8之 类
本篇文章的内容介绍的是关于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();这样定义一个属性就会触发语法错误。成员属性又分为两类:普通属性、静态属性,与常量的存储方式不同,成员属性的初始化值并不是直接用以"属性名"作为索引的哈希表存储的,而是通过数组保存的
实际只是成员属性的VALUE通过数组存储的,访问时仍然是根据以"属性名"为索引的散列表查找具体VALUE的,而这个散列表是zend_class_entry.properties_info
typedef 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)
成员方法也有静态、非静态之分,静态方法中不能使用$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
相关推荐:
以上是PHP7内核剖析8之 类 的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

PHP 8.4 带来了多项新功能、安全性改进和性能改进,同时弃用和删除了大量功能。 本指南介绍了如何在 Ubuntu、Debian 或其衍生版本上安装 PHP 8.4 或升级到 PHP 8.4

Visual Studio Code,也称为 VS Code,是一个免费的源代码编辑器 - 或集成开发环境 (IDE) - 可用于所有主要操作系统。 VS Code 拥有针对多种编程语言的大量扩展,可以轻松编写

JWT是一种基于JSON的开放标准,用于在各方之间安全地传输信息,主要用于身份验证和信息交换。1.JWT由Header、Payload和Signature三部分组成。2.JWT的工作原理包括生成JWT、验证JWT和解析Payload三个步骤。3.在PHP中使用JWT进行身份验证时,可以生成和验证JWT,并在高级用法中包含用户角色和权限信息。4.常见错误包括签名验证失败、令牌过期和Payload过大,调试技巧包括使用调试工具和日志记录。5.性能优化和最佳实践包括使用合适的签名算法、合理设置有效期、

字符串是由字符组成的序列,包括字母、数字和符号。本教程将学习如何使用不同的方法在PHP中计算给定字符串中元音的数量。英语中的元音是a、e、i、o、u,它们可以是大写或小写。 什么是元音? 元音是代表特定语音的字母字符。英语中共有五个元音,包括大写和小写: a, e, i, o, u 示例 1 输入:字符串 = "Tutorialspoint" 输出:6 解释 字符串 "Tutorialspoint" 中的元音是 u、o、i、a、o、i。总共有 6 个元

本教程演示了如何使用PHP有效地处理XML文档。 XML(可扩展的标记语言)是一种用于人类可读性和机器解析的多功能文本标记语言。它通常用于数据存储

如何在系统重启后自动设置unixsocket的权限每次系统重启后,我们都需要执行以下命令来修改unixsocket的权限:sudo...

静态绑定(static::)在PHP中实现晚期静态绑定(LSB),允许在静态上下文中引用调用类而非定义类。1)解析过程在运行时进行,2)在继承关系中向上查找调用类,3)可能带来性能开销。

PHP的魔法方法有哪些?PHP的魔法方法包括:1.\_\_construct,用于初始化对象;2.\_\_destruct,用于清理资源;3.\_\_call,处理不存在的方法调用;4.\_\_get,实现动态属性访问;5.\_\_set,实现动态属性设置。这些方法在特定情况下自动调用,提升代码的灵活性和效率。
