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