Heim >Backend-Entwicklung >PHP-Tutorial >PHP扩展开发(二)
> 上文我们学会了如何快速的进行一个PHP扩展的hello world!下面我们将学习如何传递参数###必要知识点1.变量存储结构(php 5.6 src/ZEND/zend.h)typedef union _zvalue_value { long lval; // long value double dval; // double value struct { char *val; int len; } str; HashTable *ht; // zend_object_value obj; zend_ast *ast;} zvalue_value;struct _zval_struct { // Variable information zvalue_value value; // value zend_uint refcount\__gc; zend_uchar type; // active type zend_uchar is_ref\__gc;};最终形成一个[这个就是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方法的``` 87 PHPAPI void php_var_dump(zval **struc, int level TSRMLS_DC) /* {{{ */ 88 { 89 HashTable *myht; 90 const char *class_name; 91 zend_uint class_name_len; 92 int (*php_element_dump_func)(zval** TSRMLS_DC, int, va_list, zend_hash_key*); 93 int is_temp; 94 95 if (level > 1) { 96 php_printf("%*c", level - 1, ' '); 97 } 98 99 switch (Z_TYPE_PP(struc)) { 100 case IS_BOOL: 101 php_printf("%sbool(%s)\n", COMMON, Z_LVAL_PP(struc) ? "true" : "false"); 102 break; ...... }173 line PHP_FUNCTION(var_dump) 173 { 174 zval ***args; 175 int argc; 176 int i; 177 178 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argc) == FAILURE) { 179 return; 180 } 181 182 for (i = 0; i < argc; i++) { 183 php_var_dump(args[i], 1 TSRMLS_CC); 184 } 185 efree(args); 186 }```可以发现 和上节说的一样首先定义 PHP_FUNCTION(函数名){实现}那我们发现没有参数怎么办?这里就要用到我们开始说的方法了 178行**zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argc)**明显由其获得了参数 和 参数的个数然后调用了函数的实现体到此,PHP扩展开发怎么调用函数,思路就已经很明确了。###实践我们还是依照昨天的example,今天我们写一个A+B的方法首先,我们定义一个方法``` PHP_FUNCTION(example_add){ zval ***args; int argc; int i; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argc) == FAILURE) { return; } //添加要做的操作 efree(args); }```我们加入我们要实现的A+B功能printf("%d\n",args[0]+args[1]);同样,我们添加到functions```static const zend_function_entry t2_functions[] = { //在这加入方法的定义 PHP_FE(example_add,arg_info) {NULL, NULL, NULL}}```重新编译安装,我们就可以运行```<?php example_add(3,5); ?> ```输出8