1.需要实现的细节
- 在第三节,有个调用函数的例子,我们来稍微细说下
- 然后就是平时大家定义了类里面的方法,有时候有相互调用,我们写一个例子
2.person扩展
2.1在php_person.h中增加:
PHP_METHOD(person_ce,callback);
PHP_METHOD(person_ce,setkey);
2.2 实现代码
在php_initest.h中打开全局变量设置块的注释,改成自己相要的变量如下
//新增定义
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);
}
2.3 相关内容
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中的 | ,这个表示 在它之前的参数是必须的,之后的是非必须的
2.4 扩展使用
[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"
}
- 请尊重本人劳动成功,可以随意转载但保留以下信息
- 作者:岁月经年
- 时间:2016年03月
- 首发:http://www.djhull.com