define INIT_CLASS_ENTRY_EX(class_container, class_name, class_name_len, functions) INIT_OVERLOADED_CLASS_ENTRY_EX(class_container, class_name, class_name_len, functions, NULL, NULL, NULL, NULL, NULL)
define INIT_OVERLOADED_CLASS_ENTRY_EX(class_container, class_name, class_name_len, functions, handle_fcall, handle_propget, handle_propset, handle_propunset, handle_propisset) {
const char *cl_name = class_name;
int _len = class_name_len;
class_container.name = zend_new_interned_string(cl_name, _len+1, 0 TSRMLS_CC);
if (class_container.name == cl_name) {
class_container.name = zend_strndup(cl_name, _len);
}
class_container.name_length = _len;
INIT_CLASS_ENTRY_INIT_METHODS(class_container, functions, handle_fcall, handle_propget, handle_propset, handle_propunset, handle_propisset) \
}
#define INIT_CLASS_ENTRY_INIT_METHODS(class_container, functions, handle_fcall, handle_propget, handle_propset, handle_propunset, handle_propisset) {
class_container.constructor = NULL;
class_container.destructor = NULL;
class_container.clone = NULL;
class_container.serialize = NULL;
class_container.unserialize = NULL;
class_container.create_object = NULL;
class_container.interface_gets_implemented = NULL;
class_container.get_static_method = NULL;
class_container.__call = handle_fcall;
class_container.__callstatic = NULL;
class_container.__tostring = NULL;
class_container.__get = handle_propget;
class_container.__set = handle_propset;
class_container.__unset = handle_propunset;
class_container.__isset = handle_propisset;
class_container.serialize_func = NULL;
class_container.unserialize_func = NULL;
class_container.serialize = NULL;
class_container.unserialize = NULL;
class_container.parent = NULL;
class_container.num_interfaces = 0;
class_container.traits = NULL;
class_container.num_traits = 0;
class_container.trait_aliases = NULL;
class_container.trait_precedences = NULL;
class_container.interfaces = NULL;
class_container.get_iterator = NULL;
class_container.iterator_funcs.funcs = NULL;
class_container.info.internal.module = NULL;
class_container.info.internal.builtin_functions = functions;
}
五、PHP_METHOD
PHP_METHOD(test,__construct);
PHP_METHOD(test,__destruct);
PHP_METHOD(test,setproperty);
PHP_METHOD(test,getproperty);
内核中的定义
#define PHP_METHOD ZEND_METHOD
#define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_MN(classname##_##name))
#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_v alue_used TSRMLS_DC
//等价于
void name(int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_v alue_used TSRMLS_DC )
六、zend_arg_info
typedef struct _zend_arg_info {
const char *name; //参数名称
zend_uint name_len;//长度
const char *class_name; //所属类名
zend_uint class_name_len; //类名长度
zend_bool array_type_hint;
zend_bool allow_null; //允许为空
zend_bool pass_by_reference; //引用传值
zend_bool return_reference; //引用返回
int required_num_args; //参数个数
} zend_arg_info;
接受参数.那么就要执行
ZEND_BEGIN_ARG_INFO(test___construct_arginfo, 0)
ZEND_ARG_INFO(0, url)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX定义在Zend/zend_API.h
define ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference, required_num_args) \
static const zend_arg_info name[] = { \
{ NULL, 0, NULL, 0, 0, 0, pass_rest_by_reference, return_reference, required_num_args },
ZEND_ARG_INFO(0,url)的定义如下
#define ZEND_ARG_INFO(pass_by_ref, name) { #name, sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref, 0, 0 },
最终是这样的
static const zend_arg_info name[] = {
{ NULL, 0, NULL, 0, 0, 0, pass_rest_by_reference, return_reference, required_num_args },
{ #name, sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref, 0, 0 },
};
七、定义一个类
1、申明
static zend_class_entry *test_ce;
2、添加方法
const zend_function_entry test_methods[] = {
PHP_ME(test, __construct, test___construct_arginfo, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
PHP_ME(test, __destruct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR)
PHP_ME(test, __toString, NULL, ZEND_ACC_PUBLIC)
PHP_ME(test, getMeta, NULL, ZEND_ACC_PUBLIC)
PHP_ME(test, setMeta, NULL, ZEND_ACC_PUBLIC)
{ NULL, NULL, NULL }
};
//ZEND_ACC_CTOR标示构造函数
//ZEND_ACC_DTOR标示析构函数
3、PHP_MINIT_FUNCTION中初始化
PHP_MINIT_FUNCTION(test)
{
/*定义一个temp class*/
zend_class_entry ce;
/*初始化这个class,第二个参数是class name, 第三个参数是class methods*/
INIT_CLASS_ENTRY(ce, "test", test_methods);
/*注册这个class到zend engine*/
test_ce = zend_register_internal_class(&ce TSRMLS_CC);
return SUCCESS;
}
4、定义参数
ZEND_BEGIN_ARG_INFO(test___construct_arginfo, 0)
ZEND_ARG_INFO(0, url)
ZEND_END_ARG_INFO()
5、具体方法
static PHP_METHOD(test, __construct) {
char *url;
int url_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &url, &url_len, &age) == FAILURE) {
return;
}
zval *obj;
obj = getThis();
zend_update_property_stringl(test_ce, obj, "url", sizeof("url") -1, url, url_len TSRMLS_CC);
}
6、在PHP中访问
<?php
$c = new test('http://test.com');