类与对像2(自定义object存储)

类与对像2(自定义object存储)

1,创建一个扩展

./ext_skel --extname=objects2

2,代码

//定义一个结构用于存储object
typedef struct _hello_object {
    zend_object obj;

    char *name;
    int name_len;
    long age;
} hello_object;

//object操作回调函数
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;
    zend_object_write_property_t            write_property;
    zend_object_read_dimension_t            read_dimension;
    zend_object_write_dimension_t           write_dimension;
    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;
};

创建一个object的流程

1,定义class和object handlers(回调方法)

static zend_class_entry *hello_ce;
static zend_object_handlers hello_handlers;

2,定义存储object的结构
typedef struct _hello_object {
    zend_object obj;

    char *name;
    int name_len;
    long age;
} hello_object;

3,在PHP_MINIT_FUNCTION中初始化class
static PHP_MINIT_FUNCTION(objects2){
    zend_class_entry ce;
    INIT_CLASS_ENTRY(ce, "Hello", hello_methods)

    hello_ce = zend_register_internal_class(&ce TSRMLS_CC);
    hello_ce->create_object = hello_ctor;//创建object的回调方法

    memcpy(&hello_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
    // hello_handlers->clone_obj = hello_clone;
    return SUCCESS;
}

4,实现创建object的回调方法
static zend_object_value hello_ctor(zend_class_entry *ce TSRMLS_DC) {
    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, //翻译object的回调方法
                                        NULL TSRMLS_CC);
    retval.handlers = &hello_handlers;
    return retval;
}

5,实现销毁object的回调方法
static void hello_dtor(hello_object *objval TSRMLS_CC) {
    if (objval->name) {
        efree(objval->name);
    }
    zend_object_std_dtor(&(objval->obj) TSRMLS_CC);
    efree(objval);
}

6,调用存储object的结构

#define HELLO_FETCH_OBJECT(zobj) (hello_object *)zend_object_store_get_object((zobj) TSRMLS_CC)
static PHP_METHOD(Hello, __construct) {
    hello_object *objval = HELLO_FETCH_OBJECT(getThis());
    char *name;
    int name_len;
    long age;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &name, &name_len, &age) == FAILURE) {
        return;
    }

    objval->name = estrndup(name, name_len);
    objval->name_len = name_len;
    objval->age = age;
}

//获取object指针
hello_object *obj = (hello_object *)zend_object_store_get_object(getThis() TSRMLS_CC)