PHP扩展开发(二)

上文咱们学会了如何快速的进行一个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

相关文章
相关标签/搜索