[李景山php] 深入理解PHP内核[读书笔记]--第五章:类和面向对象 --类的结构和实现

49 篇文章 0 订阅

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;// ZEND_ACC_IMLICIT_ABSTRACT_CLASS 类存在abstract 方法
     // ZEND_ACC_EXPLICIT_ABSTRACT_CLASS: 在类名称前加了 abstract 关键字
     // ZEND_ACC_FINAL_CLASS
     // ZEND_ACC_INTERFACE
     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_functinons;//方法定义入口

     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)
}

类的实现


在语法分析阶段将类分为三种类型:常规类(T_CLASS),抽象类(T_ABSTRACT T_CLASS)和final类(T_FINAL T_CLASS )。 他们分别对应的类型在内核中为:

  • 常规类(T_CLASS) 对应的type=0
  • 抽象类(T_ABSTRACT T_CLASS) 对应type=ZEND_ACC_EXPLICIT_ABSTRACT_CLASS
  • final类(T_FINAL T_CLASS) 对应type=ZEND_ACC_FINAL_CLASS

除了上面的三种类型外,类还包含有另外两种类型没有加abstract关键字的抽象类和接口:

  • 没有加abstract关键字的抽象类,它对应的type=ZEND_ACC_IMPLICIT_ABSTRACT_CLASS。由于在class前面没有abstract关键字,在语法分析时并没有分析出来这是一个抽象类,但是由于类中拥有抽象方法,在函数注册时判断成员函数是抽象方法或继承类中的成员方法是抽象方法时,会将这个类设置为此种抽象类类型。
  • 接口,其type=ZEND_ACC_INTERFACE。接口类型的区分是在interface关键字解析时设置,见interface_entry:对应的语法说明。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值