PHP 底层道理之类和对象
关于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教程栏目停止学习!
以上就是PHP 底层道理之类和对象的具体内容,更多请关注百分百源码网其它相关文章!