PHP扩展开发(二)

Wesley13
• 阅读 582

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

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
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
Easter79 Easter79
2年前
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
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Stella981 Stella981
2年前
Ecshop用户中心的收藏列表里显示商品缩略图
1)、修改includes/lib\_clips.php文件将下面代码$sql'SELECTg.goods_id,g.goods_name,g.market_price,g.shop_priceASorg_price,'.修改为$sql'SELECTg.goods_id,g.goods_nam
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这