php对象底层结构,PHP 底层原理之类和对象

728bc4e497ae519719dc45b634ed8cd1.png

对于PHPer来说,OOP是不可或缺的开发思维,但是你对php类和对象的底层实现又了解多少呢?本着知其然且知其所以然的思想,让我们一起来寻找答案~

类的底层实现可看作是之前我们讲过的变量、函数等的知识集合。所以想要理解更深入的同学最好查看下我之前的关于介绍变量、函数的文章

类的数据结构

不管是普通类还是抽象类或是接口,都存放到统一的结构体中,并且在生成中间代码时,会将此类添加到全局类列表中。当然,也是在此时,会通过类名判断该类是否已经存在,如果存在,则添加失败struct _zend_class_entry {

char type; // 和函数一样,类被拆分为两种类型:ZEND_INTERNAL_CLASS 内部类型和ZEND_USER_CLASS 用户自定义类型

char *name;// 类名称

zend_uint name_length; // 即sizeof(name) - 1

struct _zend_class_entry *parent; // 继承的父类

int refcount; // 引用数

zend_bool constants_updated;

zend_uint ce_flags;//类的类型,在编译阶段被区分是普通类,接口,抽象类

HashTable function_table; // 静态类方法和普通类方法存放集合

HashTable default_properties; // 默认属性存放集合

HashTable properties_info; // 属性信息存放集合

HashTable default_static_members;// 类本身所具有的静态变量存放集合

HashTable *static_members; // type == ZEND_USER_CLASS时,取&default_static_members;

// type == ZEND_INTERAL_CLASS时,设为NULL

HashTable constants_table; // 常量存放集合

struct _zend_function_entry *builtin_functions;// 方法定义入口

/* 魔术方法 */

//所有魔术方法单独存放,初始化时被设置为null

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 *__tostring;

union _zend_function *serialize_func;

union _zend_function *unserialize_func;

zend_class_iterator_funcs iterator_funcs;// 迭代

/* 类句柄 */

zend_object_value (*create_object)(zend_class_entry *class_type TSRMLS_DC);

zend_object_iterator *(*get_iterator)(zend_class_entry *ce, zval *object,

intby_ref TSRMLS_DC);

/* 类声明的接口 */

int(*interface_gets_implemented)(zend_class_entry *iface,

zend_class_entry *class_type TSRMLS_DC);

/* 序列化回调函数指针 */

int(*serialize)(zval *object, unsignedchar**buffer, zend_uint *buf_len,

zend_serialize_data *data TSRMLS_DC);

int(*unserialize)(zval **object, zend_class_entry *ce, constunsignedchar*buf,

zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC);

zend_class_entry **interfaces; // 类实现的接口

zend_uint num_interfaces; // 类实现的接口数

char *filename; // 类的存放文件地址 绝对地址

zend_uint line_start; // 类定义的开始行

zend_uint line_end; // 类定义的结束行

char *doc_comment;

zend_uint doc_comment_len;

struct _zend_module_entry *module; // 类所在的模块入口:EG(current_module)

};

由上面代码可以看出,类的成员变量、成员方法都是存放在各自的结构体中,而结构体的数据结构和之前讲解的变量和函数的数据结构一模一样,只不过编译后的成员变量和成员方法是存放在类结构体中而已

对象的生成

我们都知道,对象是new出来的,但是从底层来看,对象生成分为3步

第一步:根据类名去全局类列表内查找该类是否存在,如果存在,则获取存储类的变量

第二步:判断类是否是普通类(非抽象类或接口);如果是普通类则给需要创建的对象存放的zval容器分配内存,并设置容器类型为IS_OBJECT

第三步:执行对象初始化操作,将对象添加到全局对象列表(对象池)中

附上对象的数据结构:typedef struct _zend_object {

zend_class_entry *ce; //对象的类结构

HashTable *properties; //对象属性

HashTable *guards; /* protects from __get/__set ... recursion */

} zend_object;

获取和设置成员变量

获取成员变量:

第一步,获取对象的属性,从对象的properties查找是否存在与名称对应的属性,如果存在返回结果,如果不存在,转第二步

第二步,如果存在get魔术方法,则调用此方法获取变量,如果不存在,则报错

设置成员变量:

第一步,获取对象的属性,从对象的properties查找是否存在与名称对应的属性,如果存在且已有的值和需要设置的值相同,则不执行任何操作,否则执行变量赋值操作,如果不存在,转第二步

第二步,如果存在_set魔术方法,则调用此方法设置变量,如果不存在,转第三步

第三步,如果成员变量一直没有被设置过,则直接将此变量添加到对象的properties字段所在HashTable中。

总结

到今天为止,我们差不多已经将关于php的底层原理讲了一个遍了。当然,在这期间,不少同学跟我说,现在都已经逐渐开始使用php7了,你现在讲解的内容还是php5,会不会过时了?其实我讲解php5也是为讲php7作准备,php7毕竟是php5的延展,了解了php5之后,再去了解php7会更加容易些。而且php也是从php5开始才逐渐完善起来的,我们有必要了解下php5的内容。不过从下周开始,我们会开始从底层比较php7和php5的不同,敬请期待~

更多PHP相关技术文章,请访问PHP教程栏目进行学习!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/271032.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

程序默认在副屏显示_聊一款性价比极高的电竞显示器

小米在6月17日开启了小米显示器27寸165Hz版本的众筹,这台显示器的分辨率为2560x1440,也就是大家熟悉的小金刚,它与大金刚的最大区别也只是省去了G-Sync功能,而其他方面的参数几乎是一致的。那么我们今天就来聊聊这款真香的显示器。…

事务管理基础:两段锁协议、活锁、死锁相关知识整理

1、两段锁协议(Two-phase Locking Protocol) 两段锁协议是指对任何数据进行读写之前必须对数据进行加锁;在释放一个封锁之后,事务不再申请和获得任何其他封锁。两段锁协议中两段的含义:事务分为两个阶段,第…

php 空函数,PHP 中函数 isset(), empty(), is_null() 的区别

PHP 中函数 isset(), empty(), is_null() 的区别,使用 PHP 进行开发的时候,经常会用到 isset(), empty(), is_null() 这几个函数对数据进行判断,但是这是哪个函数的具体区别其实没有很好的掌握。下面我们详细讲解一下:NULL什么是 NULL&#x…

UVa11021

11021 TribblesGRAVITATION, n.“The tendency of all bodies to approach one another with a strengthproportion to the quantity of matter they contain – the quantity ofmatter they contain being ascertained by the strength of their tendencyto approach one anot…

数据库系统故障相关知识笔记

数据库系统中可能发生的故障主要包括事务故障、系统故障、介质故障、计算机病毒等。下面给大家简单整理一下相关的故障知识笔记。1、事务故障事务故障是因为程序执行错误而引起的非预期、异常终止的故障。主要有逻辑错误、系统错误导致事务的执行失败。逻辑错误:比如…

dede php分页代码,DEDECMS系统分页标签自定义二次开发

以前有给大家写过一篇自定义dedecms留言板的分页,下面我再来给大家分享一篇自定义常见的分页标签例子,希望文章对大家会有所帮助.自定搜索结果页面文章分页,在/plus文件夹中新建一个search.php文件,代码如下:require_once(dirname(__FILE__)."/../include/common.inc.php&…

数据库系备份相关知识笔记

1、数据库备份的知识介绍在互联网时代,最珍贵的财产不是计算机应用软件,更不是计算机硬件,而是企业在业务长期发展过程中积累下来的业务数据。建立网络最根本的用途是更加方便的传递、使用数据,人为原因、硬盘损坏、计算机病毒、断…

操作系统:分享6 个“吓人”的 Linux 命令

目录 1、crypt 2、kill 3、shred 5、at midnight 6、daemons 1、crypt 好吧,我们一直都有crypt。顾名思义,crypt不是存放垃圾文件的地宫或墓坑,而是加密文件内容的命令。 如今,“crypt”通常作为一个脚本而实现:通过调…

谷歌网络代理工具_谷歌更新了Dialogflow AI引擎,帮助客户创建更好的虚拟代理...

日前,谷歌发布了对其Dialogflow的一些重要更新,对话流是其呼叫中心人工智能服务的主要技术,它可以自动与呼叫中心的客户进行交互。据悉,Dialogflow是一个会话人工智能引擎,用于创建虚拟代理,可以理解和响应…

数据库恢复相关知识笔记

1、数据库恢复的原理数据库恢复的原理主要是在数据库发生故障之后,建立冗余数据,在故障发生之后利用冗余数据来完成数据库恢复。数据转储和建立日志文件是建立冗余数据常用的技术手段。一般情况下两种技术手段会同时使用。2、故障恢复的两个操作故障恢复…

oracle數據庫any,Oracle权限集合全集

alter any cluster 修改任意簇的权限alter any index 修改任意索引的权限alter any role 修改任意角色的权限alter any sequence 修改任意序列的权限alter any snapshot 修改任意快照的权限alter any table 修改任意表的权限alter any trigger 修改任意触发器的权限alter clust…

equals方法中变量在前和在后的区别

如果是两个都是变量,那就放哪都行没啥区别 如果有一个是常量一个变量的情况下,因为equals()方法是在Object类里定义的,也就是说任何对象都可以调用equals()方法,但是对象在调用方法的时候,如果对象为null那系统运行就…

空间句法软件_【特训营报名】空间句法理论与实践应用(第二期更新版)丨城市数据派...

最新线上特训营 授课老师专业过硬负责空间句法官方中文网站建设作为主要译者翻译空间句法奠基作《空间的社会逻辑》此课程为空间句法初级课程的第二期更新版课程内容更丰富更完善教学视频永久观看报名时间及价格 课程原价1000元,提前报名享优惠!4月13-19…

数据库安全性相关知识笔记​

1、数据库的恶意访问形式未经授权读取数据、未经授权修改数据、未经授权破坏数据。2、数据库安全性概念数据库安全性(Data Base Security)主要是指尽可能保护数据库不受恶意访问。3、数据库安全防护的层次数据库系统层次(DataBase System&…

摩托罗拉v8对讲机驱动软件_摩托罗拉数字机如何设置“个性”提示音

诺基亚手机的开机铃声是很多70后 80后的回忆,给心爱的“摩机”P8668i配上一段开机铃声“Hello MOTO”,既俏皮又炫酷。如果设置个性提示音,今天就给大家简单示范下。一、第一种语音提示是“文本转语音”以P8668i对讲机为例,CPS软件里面可以选择…

电脑快捷键:关于shift键的11个实用技巧

今天要和大家一起聊一下我们电脑键盘上那些关于shift键的事儿。提起电脑键盘上的shift键大家一定很熟悉,因为在平常使用电脑的时候呢会经常的用到它。 可是大家知道吗?shift按键除了我们平常使用的那些功能和作用以外,它还有11个你有可能不知…

java中final使用

final关键字可以用来修饰引用、方法和类。 1、用来修饰一个引用 如果引用为基本数据类型,则该引用为常量,该值无法修改; 如果引用为引用数据类型,比如对象、数组,则该对象、数组本身可以修改,但指向该对象或…

曲线的生成算法实现_PCGPlanet1-地形生成算法简介

比较常用的地形生成算法有三种:四叉树算法,GeoMipmap算法,移动立方体算法目前市面游戏采用的方案基本都是以这三种算法为基础实现的,下面依次进行介绍四叉树算法很经典的算法,在没有GPU的时代就已经出现了,原始算法是纯…