PHP_METHOD(person_ce,callback); PHP_METHOD(person_ce,setkey);
在php_initest.h中打开全局变量设置块的注释,改为本身相要的变量以下php
//新增定义 ZEND_BEGIN_ARG_INFO_EX(global_setkey_arg, 0, 0, 2) ZEND_ARG_INFO(0, setkey1) ZEND_ARG_INFO(0, setkey2) ZEND_END_ARG_INFO() const zend_function_entry person_functions[] = { ZEND_ME(person, __construct, global_config_arg, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR) ZEND_ME(person,doing,NULL,ZEND_ACC_PUBLIC) ZEND_ME(person,saying,NULL,ZEND_ACC_PUBLIC) //增长两个类里面的方法 ZEND_ME(person,callback,NULL,ZEND_ACC_PUBLIC) ZEND_ME(person,setkey,global_setkey_arg,ZEND_ACC_PUBLIC) ZEND_ME(person,__destruct,NULL,ZEND_ACC_PUBLIC|ZEND_ACC_DTOR) PHP_FE_END /* Must be the last line in person_functions[] */ }; ZEND_METHOD(person,setkey){ zval *param1; zval *param2; //#include <zend_API.h> //int zend_parse_parameters ( int num_args TSRMLS_DC, char* type_spec, ... ) if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|z",¶m1,¶m2) == FAILURE) { RETURN_FALSE; } zend_update_property(person_ce, getThis(), "param1", sizeof("param1")-1, param1 TSRMLS_CC); zend_update_property(person_ce, getThis(), "param2", sizeof("param2")-1, param2 TSRMLS_CC); } ZEND_METHOD(person,callback){ //#include <zend_interfaces.h> //zval* zend_call_method_with_0_params ( ... obj, zend_class_entry* obj_ce, zend_function** fn_proxy, char* function_name, ... retval ) //zval* zend_call_method_with_1_params ( ... obj, zend_class_entry* obj_ce, zend_function** fn_proxy, char* function_name, ... retval, zval* arg1 ) //zval* zend_call_method_with_2_params ( ... obj, zend_class_entry* obj_ce, zend_function** fn_proxy, char* function_name, ... retval, zval* arg1, zval* arg2 ) //zval* zend_call_method ( zval** object_pp, zend_class_entry* obj_ce, zend_function** fn_proxy, char* function_name, int function_name_len, zval** retval_ptr_ptr, int param_count, zval* arg1, zval* arg2, magic TSRMLS_DC ) zend_call_method_with_0_params(getThis(),person_ce,NULL,"doing",return_value); } ZEND_METHOD(person,callback_function){ //声明一个对象变量 zval *object_name; object_init_ex(object_name,person_ce); //声明函数名变量 zval function_name; ZVAL_STRING(&function_name,"doing"); //声明承接返回值的变量 zval retval; // 调用类的 doing 方法 if(call_user_function(EG(function_table), object_name, &function_name, &retval, 0, NULL)==FAILURE){ RETURN_NULL(); // zend_error(E_ERROR,"call person doing error"); } //释放资源空间 *return_value=*retval; zval_copy_ctor(return_value); zval_ptr_dtor(&retval); }
type_spec是格式化字符串,其常见的含义以下:
参数 表明着的类型
b Boolean l Integer 整型 d Floating point 浮点型 s String 字符串 r Resource 资源 a Array 数组 o Object instance 对象 O Object instance of a specified type 特定类型的对象 z Non-specific zval 任意类型~ Z zval**类型 f 表示函数、方法名称 对应的接收变量类型 参数 对应C里的数据类型 b zend_bool l long d double s char*, int 前者接收指针,后者接收长度 r zval* a zval* o zval* O zval*, zend_class_entry* z zval* Z zval** zend_parse_parameters中的 | ,这个表示 在它以前的参数是必须的,以后的是非必须的
[root@bogon tests]# cat test.php <?php $n = new person(array('key'=>'value')); $n->setkey('testparam1','testparam2'); var_dump($n->param1); var_dump($n->param2); [root@bogon tests]# php test.php string(10) "testparam1" string(10) "testparam2" array(1) { ["key"]=> string(5) "value" }