PHP扩展开发(二)

上文我们学会了如何快速的进行一个PHP扩展的hello world! 下面我们将学习如何传递参数

###必要知识点

1.变量存储结构(php 5.6 src/ZEND/zend.h)

1typedef union _zvalue_value { 2 long lval; // long value 3 double dval; // double value 4 struct { 5 char *val; 6 int len; 7 } str; 8 HashTable *ht; // 9 zend_object_value obj; 10 zend_ast *ast; 11} zvalue_value; 12 13struct _zval_struct { 14 // Variable information 15 zvalue_value value; // value 16 zend_uint refcount\__gc; 17 zend_uchar type; // active type 18 zend_uchar is_ref\__gc; 19};

最终形成一个[这个就是PHP的变量] typedef struct _zval_struct zval; 其实际值存储在 zval.value 判断是否为引用 is_ref__gc 判断引用的次数 refcount gc [PHP的写时复制特性] 判断值的类型 type

###源码分析 我们打开zend_API.c 可以看到很多关于变量的处理的函数。

比如 ZEND_API int zend_get_parameters(int ht, int param_count, ...)

ZEND_API int _zend_get_parameters_array(int ht, int param_count, zval **argument_array TSRMLS_DC)

ZEND_API int zend_get_parameters_ex(int param_count, ...)

ZEND_API int _zend_get_parameters_array_ex(int param_count, zval ***argument_array TSRMLS_DC)

ZEND_API int zend_parse_parameters ......

我们来参考一下原来的代码。 打开文件 phpsrc/ext/standard/var.c

我们看PHP是如何实现var_dump方法的

1 87 PHPAPI void php_var_dump(zval **struc, int level TSRMLS_DC) /* {{{ */ 2 88 { 3 89 HashTable *myht; 4 90 const char *class_name; 5 91 zend_uint class_name_len; 6 92 int (*php_element_dump_func)(zval** TSRMLS_DC, int, va_list, zend_hash_key*); 7 93 int is_temp; 8 94 9 95 if (level > 1) { 10 96 php_printf("%*c", level - 1, ' '); 11 97 } 12 98 13 99 switch (Z_TYPE_PP(struc)) { 14 100 case IS_BOOL: 15 101 php_printf("%sbool(%s)\n", COMMON, Z_LVAL_PP(struc) ? "true" : "false"); 16 102 break; 17 18 ...... 19 } 20 21 22173 line 23PHP_FUNCTION(var_dump) 24 173 { 25 174 zval ***args; 26 175 int argc; 27 176 int i; 28 177 29 178 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argc) == FAILURE) { 30 179 return; 31 180 } 32 181 33 182 for (i = 0; i < argc; i++) { 34 183 php_var_dump(args[i], 1 TSRMLS_CC); 35 184 } 36 185 efree(args); 37 186 } 38

可以发现 和上节说的一样 首先定义 PHP_FUNCTION(函数名){实现} 那我们发现没有参数怎么办?

这里就要用到我们开始说的方法了 178行 zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argc)

明显由其获得了 参数 和 参数的个数

然后调用了函数的实现体

到此,PHP扩展开发怎么调用函数,思路就已经很明确了。

###实践 我们还是依照昨天的example,今天我们写一个A+B的方法

首先,我们定义一个方法

1 PHP_FUNCTION(example_add){ 2 long a,b; 3 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &a, &b) == FAILURE) { 4 return; 5 } 6 7 //添加要做的操作 8 9 }

我们加入我们要实现的A+B功能

printf("%d\n",a+b);

同样,我们添加到functions

1static const zend_function_entry t2_functions[] = { 2 //在这加入方法的定义 3 PHP_FE(example_add,NULL) 4 {NULL, NULL, NULL} 5}

重新编译安装,我们就可以运行

<?php example_add(3,5); ?>  

输出8

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

swap空间的增减方法

(1)增大swap空间去激活swap交换区:swapoff v /dev/vg00/lvswap扩展交换lv:lvextend L 10G /dev/vg00/lvswap重新生成swap交换区:mkswap /dev/vg00/lvswap激活新生成的交换区:swapon v /dev/vg00/lvswap