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: 這個保存的對象相關操做的一些函數指針,好比成員屬性的讀寫、成員方法的獲取、對象的銷燬/克隆等等,這些操做接口都有默認的函數ui
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: 普通成員屬性哈希表,對象建立之初這個值爲NULLspa
properties_table: 成員屬性數組,它是一個數組,zend_object
是個變長結構體,分配時會根據非靜態屬性的數量肯定其大小debug
普通成員屬性的查找比較容易理解,首先是從zend_class的屬性信息哈希表中找到zend_property_info,並判斷其可見性(public、private、protected),若是能夠訪問則直接根據屬性的offset在zend_object.properties_table數組中取到屬性值指針