php对象的实现
1.对象的数据结构非常简单
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]; //普通属性值数组 };
handle: 一次request期间对象的编号,每个对象都有一个唯一的编号,与创建先后顺序有关,主要在垃圾回收时用
ce: 所属类的zend_class_entry
handlers: 这个保存的对象相关操作的一些函数指针,比如成员属性的读写、成员方法的获取、对象的销毁/克隆等等,这些操作接口都有默认的函数
struct _zend_object_handlers { int offset; zend_object_free_obj_t free_obj; //释放对象 zend_object_dtor_obj_t dtor_obj; //销毁对象 zend_object_clone_obj_t clone_obj;//复制对象 zend_object_read_property_t read_property; //读取成员属性 zend_object_write_property_t write_property;//修改成员属性 ... } //默认值处理handler ZEND_API zend_object_handlers std_object_handlers = { 0, zend_object_std_dtor, /* free_obj */ zend_objects_destroy_object, /* dtor_obj */ zend_objects_clone_obj, /* clone_obj */ zend_std_read_property, /* read_property */ zend_std_write_property, /* write_property */ zend_std_read_dimension, /* read_dimension */ zend_std_write_dimension, /* write_dimension */ zend_std_get_property_ptr_ptr, /* get_property_ptr_ptr */ NULL, /* get */ NULL, /* set */ zend_std_has_property, /* has_property */ zend_std_unset_property, /* unset_property */ zend_std_has_dimension, /* has_dimension */ zend_std_unset_dimension, /* unset_dimension */ zend_std_get_properties, /* get_properties */ zend_std_get_method, /* get_method */ NULL, /* call_method */ zend_std_get_constructor, /* get_constructor */ zend_std_object_get_class_name, /* get_class_name */ zend_std_compare_objects, /* compare_objects */ zend_std_cast_object_tostring, /* cast_object */ NULL, /* count_elements */ zend_std_get_debug_info, /* get_debug_info */ zend_std_get_closure, /* get_closure */ zend_std_get_gc, /* get_gc */ NULL, /* do_operation */ NULL, /* compare */ }
properties: 普通成员属性哈希表,对象创建之初这个值为NULL
properties_table: 成员属性数组,它是一个数组,zend_object
是个变长结构体,分配时会根据非静态属性的数量确定其大小
普通成员属性的查找比较容易理解,首先是从zend_class的属性信息哈希表中找到zend_property_info,并判断其可见性(public、private、protected),如果可以访问则直接根据属性的offset在zend_object.properties_table数组中取到属性值
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步