上文咱們學會了如何快速的進行一個PHP擴展的hello world! 下面咱們將學習如何傳遞參數php
###必要知識點函數
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 能夠看到不少關於變量的處理的函數。ui
好比 ZEND_API int zend_get_parameters(int ht, int param_count, ...)code
ZEND_API int _zend_get_parameters_array(int ht, int param_count, zval **argument_array TSRMLS_DC)orm
ZEND_API int zend_get_parameters_ex(int param_count, ...)element
ZEND_API int _zend_get_parameters_array_ex(int param_count, zval ***argument_array TSRMLS_DC)開發
ZEND_API int zend_parse_parameters ......get
咱們來參考一下原來的代碼。 打開文件 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){ long a,b; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &a, &b) == FAILURE) { return; } //添加要作的操做 }
咱們加入咱們要實現的A+B功能
printf("%d\n",a+b);
一樣,咱們添加到functions
static const zend_function_entry t2_functions[] = { //在這加入方法的定義 PHP_FE(example_add,NULL) {NULL, NULL, NULL} }
從新編譯安裝,咱們就能夠運行
<?php example_add(3,5); ?>
輸出8