[php-src]扩展中封装业务与 call_user_function 的使用建议
内容均以php5.6.14为例.
从一个封装 uniqid 的例子来讲。
/* {{{ wrapper of uniqid */
PHP_FUNCTION(fox)
{
// #1.
zval *prefix, *more = NULL;
zval function, *params[] = {}; // #2.
if ( zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|z", &prefix, &more) == FAILURE ) {
RETURN_FALSE;
} params[] = prefix;
if (more) {
params[] = more;
} // #3.
ZVAL_STRING(&function, "uniqid", );
// #4.
if ( call_user_function(EG(function_table), NULL, &function, return_value, ZEND_NUM_ARGS(), params TSRMLS_CC) == FAILURE ) {
if (return_value) {
zval_dtor(return_value);
}
zend_error(E_WARNING, "%s() calling %s() failed.", get_active_function_name(TSRMLS_C), Z_STRVAL(function));
RETURN_FALSE;
} RETURN_STRING(Z_STRVAL_P(return_value), );
}
/* }}} */
#1.
zval 不赋值默认是非空,不要随意给 声明的 zval 赋值为 NULL,除非你知道自己在干什么,比方用在判断是否有传参;
如果你想对可选的参数使用默认值 farwish,可以像下面这样 (非用于上例):
if (more == NULL) {
MAKE_STD_ZVAL(more);
Z_STRVAL_P(more) = "farwish";
Z_STRLEN_P(more) = strlen("farwish");
Z_TYPE_P(more) = IS_STRING;
}
params[] = more;
还有别忘了 call_user_function 中的参数个数就不能再用 ZEND_NUM_ARGS(),写固定值 2 就可以了。
#2.
接收的参数类型必须用双引号包裹,为了避免其它地方也遇到这种错误,最好后面统一都用双引号。
如果接收的参数含 char *name 类型的, 别忘了要有 uint *len 跟在它后面传入。
#3. #4.
如果开头声明的是 zval *function, 并且 ZVAL_STRING 赋值 和 call_user_function 的调用都传 function, 编译能通过, 但是使用会segmentaion fault;测试证明, ZVAL_STRING 第一个参数一定是指向 zval 的地址, 而不是简单的传 zval *, 因为宏中做了 zval *__z = (z) 这么一件事, 如果 z 已经是指针, 那么值就不对了.
./Zend/zend_execute_API.c:575
int call_user_function(HashTable *function_table, zval **object_pp, zval *function_name, zval *retval_ptr, zend_uint param_count, zval *params[] TSRMLS_DC)
zval function_name, retval_ptr;
Thats all.
开发文档:https://github.com/farwish/php-core-hack
Link:http://www.cnblogs.com/farwish/p/5635429.html
[php-src]扩展中封装业务与 call_user_function 的使用建议的更多相关文章
- JS组件系列——在ABP中封装BootstrapTable
前言:关于ABP框架,博主关注差不多有两年了吧,一直迟迟没有尝试.一方面博主觉得像这种复杂的开发框架肯定有它的过人之处,系统的稳定性和健壮性比一般的开源框架肯定强很多,可是另一方面每每想到它繁琐的封装 ...
- 减少存储过程封装业务逻辑-web开发与传统软件开发的思维模式不同
本篇文章讨论并不是:不要使用存储过程,因为有些事情还是要存储过程来完成,不可能不用.而是关于:"业务逻辑是不是要封装在存储过程中实现,这样子php.java等就是调用存储过程". ...
- Chrome扩展开发之二——Chrome扩展中脚本的运行机制和通信方式
目录: 0.Chrome扩展开发(Gmail附件管理助手)系列之〇——概述 1.Chrome扩展开发之一——Chrome扩展的文件结构 2.Chrome扩展开发之二——Chrome扩展中脚本的运行机制 ...
- Chrome扩展开发之三——Chrome扩展中的数据本地存储和下载
目录: 0.Chrome扩展开发(Gmail附件管理助手)系列之〇——概述 1.Chrome扩展开发之一——Chrome扩展的文件结构 2.Chrome扩展开发之二——Chrome扩展中脚本的运行机制 ...
- 直播开始:'云榨汁机'诞生记--聊聊JavaScript中的'业务建模'
闭包是JavaScript中的一个重要特性,在之前的博文中,我们说闭包是一个'看似简单,其实很有内涵'的特性.当我们用JavaScript来实现相对复杂的业务建模时,我们可以如何利用'闭包'这个特性呢 ...
- AngularJS之使用控制器封装业务逻辑
AngularJS之使用控制器封装业务逻辑 控制器的作用 我们知道,在AngularJS中,实现数据绑定的核心是scope对象.那么控制器又有什么用呢? 简单地说,没有控制器/controller,我 ...
- main.js中封装全局登录函数
1. 在 main.js 中封装全局登录函数 通过 vue 对象的原型扩展,可以扩展一个函数,这样这个函数就可以在每一个界面通过类似指向对象的方式,去访问这个函数. 如下是 main.js 扩展的函数 ...
- 示例:WPF中自定义StoryBoarService在代码中封装StoryBoard、Animation用于简化动画编写
原文:示例:WPF中自定义StoryBoarService在代码中封装StoryBoard.Animation用于简化动画编写 一.目的:通过对StoryBoard和Animation的封装来简化动画 ...
- PHP 使用 mcrypt 扩展中的 mcrypt_encrypt() 和 mcrypt_decrypt() 对数据进行加密和解密
<?php /* 使用 mcrypt 扩展中的 mcrypt_encrypt() 和 mcrypt_decrypt() 对数据进行加密和解密 */ // 加密 $algorithm = MCRY ...
随机推荐
- python---进程、线程
一.进程 二.线程 1,使用Thread类创建线程 #!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'zhoufeng' impor ...
- DHCP snooping
DHCP snooping 技术介绍 DHCP监听(DHCP Snooping)是一种DHCP安全特性.Cisco交换机支持在每个VLAN基础上启用DHCP监听特性.通过这种特性,交换机能够拦截第 ...
- HDOJ(2438)几何里的三分
Turn the corner http://acm.hdu.edu.cn/showproblem.php?pid=2438 题目:一辆车能否在一个路口拐弯,看图就很明白啦. 算法:见下图,只要求出图 ...
- C#与Java的比较
C#与Java的比较 写完后得知维基百科里有更加全面得多的比较: http://en.wikipedia.org/wiki/Comparison_of_C_Sharp_and_Java NET(C#) ...
- zTree入门-最简单的树
最近发现项目中很多地方都是树形菜单,而这些树形菜单都是使用树形插件zTree来制作的,所以就想自学一下zTree,参照官方文档写了一个简单的案例,使用zTree做了 一个最简单的树形结构. 案例:zT ...
- Python监控网站接口值
Python监控网站接口值: #!/usr/bin/env python # -*- coding: utf-8 -*- __author__ = 'liudong' import urllib,sy ...
- fedora25 下配置samba
本例是在 / 目录下建立share 文件夹为例 Sudo dnf install samba samba-common samba-clientsudo mkdir /share sudo chmod ...
- DIOCP之DEMO-Echo卡死问题分析
最近很多新朋友在调试echo这个例程时发现,总是卡死客户端或服务器端,这是因为客户端的接收数据用的memo没有处理接受到的行数,导致超过最大行数,而卡死界面,只需要如下操作就可以解决: 引用弦子的:虽 ...
- iOS高效开发必备的10款Objective-C类库
http://blog.csdn.net/yhawaii/article/details/7392988
- 驱动开发学习笔记. 0.07 Uboot链接地址 加载地址 和 链接脚本地址
驱动开发学习笔记. 0.07 Uboot链接地址 加载地址 和 链接脚本地址 最近重新看了乾龙_Heron的<ARM 上电启动及 Uboot 代码分析>(下简称<代码分析>) ...