当前位置: 首页 > 后端技术 > PHP

php和对象的底层原理

时间:2023-03-30 02:43:25 PHP

对于PHPer来说,OOP是不可或缺的开发思想,但是对于php类和对象的底层实现你又了解多少呢?本着知其然、知其所以然的思路,让我们一起来寻找答案吧~类的底层实现可以看作是我们之前讲过的变量、函数等的知识集合。所以想更深入了解的同学可以看看我之前介绍变量和函数的文章。类的数据结构,无论是普通类、抽象类还是接口,都存储在一个统一的结构中,在生成代码的中间,将这个类添加到全局类列表中。当然这时候会根据类名来判断类是否已经存在。如果存在,添加将失败。struct_zend_class_entry{字符类型;//和函数一样,类也分为两种类型:ZEND_INTERNAL_CLASS内部类型和ZEND_USER_CLASS用户定义类型char*name;//类名zend_uintname_length;//sizeof(name)-1struct _zend_class_entry*parent;//继承父类int refcount;//引用数zend_boolconstants_updated;zend_uintce_flags;//类的类型在编译阶段分为普通类、接口和抽象类HashTablefunction_table;//静态类方法和普通类方法存储集合HashTabledefault_properties;//默认属性存储集合HashTableproperties_info;//属性信息存储集HashTabledefault_static_members;//类本身的静态变量存储集HashTable*static_members;//当type==ZEND_USER_CLASS时,取&default_static_members;//类型==ZEND_INTERAL_CLASS,设置为NULLHashTableconstants_table;//常量存储集合struct_zend_function_entry*builtin_functions;//方法定义入口/*magicmethod*///所有magic方法单独存储,初始化时设置为nullunion_zend_function*constructor;union_zend_function*析构函数;大学在_zend_function*克隆上;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_funcsiterator_funcs;//代/*类句柄*/zend_object_value(*create_object)(zend_class_entry*class_typeTSRMLS_DC);zend_object_iterator*(*get_iterator)(zend_class_entry*ce,zval*object,intby_refTSRMLS_DC);/*类声明的接口*/int(*interface_gets_implemented)(zend_class_entry*iface,zend_class_entry*class_typeTSRMLS_DC);/*序列化回调函数指针*/int(*serialize)(zval*object,unsignedchar**buffer,zend_uint*buf_len,zend_serialize_data*dataTSRMLS_DC);int(*unserialize)(zval**object,zend_class_entry*ce,constunsignedchar*buf,zend_uintbuf_len,zend_unserialize_data*数据TSRMLS_DC);zend_class_entry**接口;//由类zend_uintnum_interfaces实现的接口;//类实现的接口数char*filename;//类的存储文件地址的绝对地址zend_uintline_start;//类定义的起始行zend_uintline_end;//类定义的结束行char*doc_comment;zend_uintdoc_comment_len;结构_zend_module_entry*模块;//该类所在的模块入口:EG(current_module)};从上面的代码可以看出,类的成员变量和成员方法都存储在各自的结构体中,而结构体的数据结构与之前讲解的变量和函数的数据结构完全一样,除了编译后的成员变量和成员方法存放在类结构中。对象的生成我们都知道对象是new的,但是从底层来说,对象的生成分为三个步骤。第一步:根据类名,到全局类列表中查找该类是否存在。如果存在,则获取存储类的变量。第二步1:判断类是否为普通类(非抽象类或接口);如果是普通类,则为存放待创建对象的zval容器分配内存,并设置容器类型为IS_OBJECT第三步:进行对象初始化操作,并将对象添加到全局对象列表(对象池)并附上对象的数据结构:typedefstruct_zend_object{zend_class_entry*ce;//对象类结构HashTable*properties;//对象属性HashTable*guards;/*防止__get/__set...递归*/}zend_object;获取和设置成员变量获取成员变量:第一步是获取对象的属性,从对象的属性中找出是否有名字对应的属性。如果有返回结果,如果不存在,则转第二步第二步,如果有get魔术方法,调用该方法获取变量,如果不存在,则报错设置成员变量:第一步是获取对象的属性,从对象的属性es查找是否有名称对应的属性。如果存在,并且存在的值与需要设置的值相同,则不进行任何操作。否则,将执行变量赋值操作。如果不存在,则转到第二步。如果存在_set魔术方法,则调用该方法设置变量,如果不存在,进入第三步对象所在的properties字段至此,我们已经差不多讲完了PHP的底层原理。当然,这期间也有很多同学跟我说,他们现在已经逐渐开始使用php7了,而你现在讲解的内容还是php5,会不会过时了?其实我对php5的讲解也是为php7做的准备。毕竟php7是php5的扩展。了解了php5之后,再了解php7会比较容易。而且php从php5开始逐步完善。我们需要了解php5的内容。不过从下周开始,我们会从底层开始比较php7和php5的区别,敬请期待~