zend_object_handlers dog_object_handlers;
zend_class_entry *dog_ce;
struct dog_object {
zend_object std; // PHP 标准类
Dog *dog; // dog 类
};
// 释放内存
void dog_free_storage(void *object TSRMLS_DC)
{
dog_object *obj = (dog_object *)object;
delete obj->dog;
zend_hash_destroy(obj->std.properties);
FREE_HASHTABLE(obj->std.properties);
efree(obj);
}
// 创建内置PHP 类,其实类就是一个 zend hash
zend_object_value dog_create_handler(zend_class_entry *type TSRMLS_DC)
{
zval *tmp;
zend_object_value retval;
dog_object *obj = (dog_object *)emalloc(sizeof(dog_object));
memset(obj, 0, sizeof(dog_object));
obj->std.ce = type;
ALLOC_HASHTABLE(obj->std.properties);
zend_hash_init(obj->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
zend_hash_copy(obj->std.properties, &type->default_properties,
(copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *));
retval.handle = zend_objects_store_put(obj, NULL,
dog_free_storage, NULL TSRMLS_CC);
retval.handlers = &dog_object_handlers;
return retval;
}
PHP_METHOD(Dog, __construct)
{
string name;
Dog *dog = NULL;
zval *object = getThis();
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, “s”, &name) == FAILURE) {
RETURN_NULL();
}
dog = new Dog(name);
dog_object *obj = (dog_object *)zend_object_store_get_object(object TSRMLS_CC);
obj->dog = dog;
}
PHP_METHOD(Dog, bark)
{
Dog *dog;
dog_object *obj = (dog_object *)zend_object_store_get_object(
getThis() TSRMLS_CC);
dog = obj->dog;
if (dog != NULL) {
dog->bark();
}
}
function_entry dog_methods[] = {
PHP_ME(Dog, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
PHP_ME(Dog, bake, NULL, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL}
};
PHP_MINIT_FUNCTION(cplusplusdog)
{
zend_class_entry ce;
INIT_CLASS_ENTRY(ce, “Dog”, dog_methods);
dog_ce = zend_register_internal_class(&ce TSRMLS_CC);
dog_ce->create_object = dog_create_handler;
memcpy(&dog_object_handlers,
zend_get_std_object_handlers(), sizeof(zend_object_handlers));
dog_object_handlers.clone_obj = NULL;
return SUCCESS;
}