Skip to content

Latest commit

 

History

History
125 lines (91 loc) · 5.52 KB

11.md

File metadata and controls

125 lines (91 loc) · 5.52 KB

类与对像3(object handlers)

1,创建一个扩展

./ext_skel --extname=objects3

2,object handlers定义

typedef zval *(*zend_object_read_property_t)(zval *object, zval *member, int type, const struct _zend_literal *key TSRMLS_DC);
typedef zval *(*zend_object_read_dimension_t)(zval *object, zval *offset, int type TSRMLS_DC);
typedef void (*zend_object_write_property_t)(zval *object, zval *member, zval *value, const struct _zend_literal *key TSRMLS_DC);
typedef void (*zend_object_write_dimension_t)(zval *object, zval *offset, zval *value TSRMLS_DC);
typedef zval **(*zend_object_get_property_ptr_ptr_t)(zval *object, zval *member, int type, const struct _zend_literal *key TSRMLS_DC);
typedef void (*zend_object_set_t)(zval **object, zval *value TSRMLS_DC);
typedef zval* (*zend_object_get_t)(zval *object TSRMLS_DC);
typedef int (*zend_object_has_property_t)(zval *object, zval *member, int has_set_exists, const struct _zend_literal *key TSRMLS_DC);
typedef int (*zend_object_has_dimension_t)(zval *object, zval *member, int check_empty TSRMLS_DC);
typedef void (*zend_object_unset_property_t)(zval *object, zval *member, const struct _zend_literal *key TSRMLS_DC);
typedef void (*zend_object_unset_dimension_t)(zval *object, zval *offset TSRMLS_DC);
typedef HashTable *(*zend_object_get_properties_t)(zval *object TSRMLS_DC);
typedef HashTable *(*zend_object_get_debug_info_t)(zval *object, int *is_temp TSRMLS_DC);

typedef int (*zend_object_call_method_t)(const char *method, INTERNAL_FUNCTION_PARAMETERS);
typedef union _zend_function *(*zend_object_get_method_t)(zval **object_ptr, char *method, int method_len, const struct _zend_literal *key TSRMLS_DC);
typedef union _zend_function *(*zend_object_get_constructor_t)(zval *object TSRMLS_DC);


typedef void (*zend_object_add_ref_t)(zval *object TSRMLS_DC);
typedef void (*zend_object_del_ref_t)(zval *object TSRMLS_DC);
typedef void (*zend_object_delete_obj_t)(zval *object TSRMLS_DC);
typedef zend_object_value (*zend_object_clone_obj_t)(zval *object TSRMLS_DC);

typedef zend_class_entry *(*zend_object_get_class_entry_t)(const zval *object TSRMLS_DC);
typedef int (*zend_object_get_class_name_t)(const zval *object, const char **class_name, zend_uint *class_name_len, int parent TSRMLS_DC);
typedef int (*zend_object_compare_t)(zval *object1, zval *object2 TSRMLS_DC);


typedef int (*zend_object_cast_t)(zval *readobj, zval *retval, int type TSRMLS_DC);


typedef int (*zend_object_count_elements_t)(zval *object, long *count TSRMLS_DC);

typedef int (*zend_object_get_closure_t)(zval *obj, zend_class_entry **ce_ptr, union _zend_function **fptr_ptr, zval **zobj_ptr TSRMLS_DC);

typedef HashTable *(*zend_object_get_gc_t)(zval *object, zval ***table, int *n TSRMLS_DC);

#所以后缀带_dimension的都是以$obj[foo]的方式访问对像,其他的是以 $obj->foo访问对像
struct _zend_object_handlers {
	/* general object functions */
	zend_object_add_ref_t					add_ref;    #添加引用
	zend_object_del_ref_t					del_ref;    #删除引用
	zend_object_clone_obj_t					clone_obj;  #克隆对像
	/* individual object functions */
	zend_object_read_property_t				read_property; #$obj->foo方式读取属性值
	zend_object_write_property_t			write_property; #$obj->foo方式写入属性值
	zend_object_read_dimension_t			read_dimension; #$obj[foo]方式读取属性值
	zend_object_write_dimension_t			write_dimension; #$obj[foo]方式写入属性值
	zend_object_get_property_ptr_ptr_t		get_property_ptr_ptr;
	zend_object_get_t						get;
	zend_object_set_t						set;
	zend_object_has_property_t				has_property;
	zend_object_unset_property_t			unset_property;
	zend_object_has_dimension_t				has_dimension;
	zend_object_unset_dimension_t			unset_dimension;
	zend_object_get_properties_t			get_properties;
	zend_object_get_method_t				get_method;
	zend_object_call_method_t				call_method;
	zend_object_get_constructor_t			get_constructor;
	zend_object_get_class_entry_t			get_class_entry;
	zend_object_get_class_name_t			get_class_name;
	zend_object_compare_t					compare_objects;
	zend_object_cast_t						cast_object;
	zend_object_count_elements_t			count_elements;
	zend_object_get_debug_info_t			get_debug_info;
	zend_object_get_closure_t				get_closure;
	zend_object_get_gc_t					get_gc;
};

extern ZEND_API zend_object_handlers std_object_handlers;

3,添加object handlers

1,定义 handlers

static zend_object_handlers hello_handlers;

2,初始化 handlers

memcpy(&hello_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
hello_handlers.clone_obj = hello_clone;
//hello_handlers.get = hello_get;
hello_handlers.count_elements = hello_count_elements;

3,设置 object 的 handlers

hello_object *objval = emalloc(sizeof(hello_object));
memset(objval, 0, sizeof(hello_object));

zend_object_value retval;
zend_object_std_init(&(objval->obj), ce TSRMLS_CC);

retval.handle = zend_objects_store_put(objval , 
                                        NULL, 
                                        (zend_objects_free_object_storage_t)hello_dtor, 
                                        NULL TSRMLS_CC);
retval.handlers = &hello_handlers;
	
4,实现handlers

static int hello_count_elements(zval *object, long *count TSRMLS_DC) {
	zend_object_handlers *zh = zend_get_std_object_handlers();
	php_printf("count: %ld\n", *count);
	*count = 5;
	return SUCCESS;
}

4,测试php

$obj = new Hello("leon", 32);
echo "obj count:" . count($obj)."\n"; //结果为5