php7扩展开发[5]本类内函数调用

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",&param1,&param2) == 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
 
posted @ 2016-04-06 15:53  岁月经年  阅读(780)  评论(0编辑  收藏  举报