PHP扩展编写点滴 技巧收集


Posted in PHP onMarch 09, 2010

红色部分是我的注释。
更多信息参看:

1.常用的通用功能已经封装好了,在如zen_API.h 头文件中,不用费力查看内部细节,浪费时间。(参考:Extending and Embedding PHP 的附录A)
2.在terminal中运行测试程序,可以看到扩展的内部错误输出,这一点对于解决内存泄漏问题尤其重要。(编译一个debug 的 lib)
3.开发过程中修改Makefile中的“CFLAGS = -g -O2”,去掉优化选项,增加-Wall和-pedantic,便于调试和显示编译警告;
4.某zval*,但其strval非拷贝的,不可用zval_ptr_dtor(zval**),要用efree(void*)。
5.terminal中的$_SERVER['PWD']有值,但是无法通过zend_getenv()取得,原因应该是该值无意义或不可靠。
6.调用“导出函数”,可利用INTERNAL_FUNCTION_PARAM_PASSTHRU传参;声明的非导出函数可通过INTERNAL_FUNCTION_PARAM使用“导出函数”的参数。
7.注意:RETURN_TYPE用在选择分之和循环等处时,最好置于花括号中,
或者不用分号,因为:#define RETURN_BOOL(b) { RETVAL_BOOL(b); return; }。
8.如果函数的参数是引用的,且非标量,要先析构,以防内存泄露。
9.抛出异常前最好判断EG(exception)中是否已经存在异常,否则会造成内存泄露。
10.当Web服务器API是ISAPI (IIS)的时候,zend_getenv函数是不起作用的。
11.向zend_stack_push()传入数据指针,实际存储(copy)的是该指针指向的数据,换句话说,传入的应该是要存储的数据的指针。
ZEND_API int zend_stack_push(zend_stack *stack, void *element, int size);
ZEND_API int zend_stack_top(zend_stack *stack, void **element);
其中,size == sizeof(*element);
类似地,zend_hash也是如此,比较zend_hash_update和zend_hash_find。
12.使用add_assoc_zval(HashTable*, const char*, zval*)存储的是zval*,而非zval,因此,
存储用户传入的参数时候,要先拷贝一份新的zval,否则会发生不可预料的事情。
13.zval_dtor(zval*)释放变量及其内部的引用内存,zval_ptr_dtor(zval**)先检查refcount
再决定是否调用zval_dtor(zval*),zval_copy_dtor(zval*)仅执行深层的拷贝,即只拷贝
起内部引用的内存,而不拷贝zval;

14.如使用VC编译win的动态链接库,而且代码中调用了zend函数,如zend_getenv,在zend.h中定义为:

extern "C" {
extern ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
}
需要引入该函数,如要使用ZEND_API,需要事先取消LIBZEND_EXPORTS(包括VC“设置”中的预处理定义),或者使用ZEND_DLIMPORT,
ZEND_DLIMPORT char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
下面取自:zend_config.w32.h

#ifdef LIBZEND_EXPORTS 
# define ZEND_API __declspec(dllexport) 
#else 
# define ZEND_API __declspec(dllimport) 
#endif 
#define ZEND_DLEXPORT __declspec(dllexport) 
#define ZEND_DLIMPORT __declspec(dllimport)

executor_globals_id也需要作如下声明:
ZEND_DLIMPORT int executor_globals_id;
(这个比较有用,如果你要手工编译某些扩展的时候,比如我在编译sqlite3这个扩展的时候,就遇到这个问题。)
PHP 相关文章推荐
PHP 定界符 使用技巧
Jun 14 PHP
Php中文件下载功能实现超详细流程分析
Jun 13 PHP
基于PHP选项与信息函数的使用详解
May 10 PHP
探讨捕获php错误信息方法的详解
Jun 09 PHP
关于更改Zend Studio/Eclipse代码风格主题的介绍
Jun 23 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十六)
Jun 30 PHP
PHP中使用sleep函数实现定时任务实例分享
Aug 21 PHP
PHP使用memcache缓存技术提高响应速度的方法
Dec 26 PHP
PHP简单操作MongoDB的方法(安装及增删改查)
May 26 PHP
详解PHP队列的实现
Mar 14 PHP
使用Zookeeper分布式部署PHP应用程序
Mar 15 PHP
Git命令之分支详解
Mar 02 PHP
php 修改zen-cart下单和付款流程以防止漏单
Mar 08 #PHP
PHP 最大运行时间 max_execution_time修改方法
Mar 08 #PHP
php ss7.5的数据调用 (笔记)
Mar 08 #PHP
phpmyadmin 常用选项设置详解版
Mar 07 #PHP
PHPMYADMIN 简明安装教程 推荐
Mar 07 #PHP
THINKPHP+JS实现缩放图片式截图的实现
Mar 07 #PHP
PHP用mysql数据库存储session的代码
Mar 05 #PHP
You might like
世界收音机发展史
2021/03/01 无线电
PHP文件缓存类示例分享
2015/01/30 PHP
PHP闭包定义与使用简单示例
2018/04/13 PHP
Yii2.0框架behaviors方法使用实例分析
2019/09/30 PHP
JavaScript的parseInt 进制问题
2009/05/07 Javascript
Javascript 实现复制(Copy)动作方法大全
2014/06/20 Javascript
jquery隔行换色效果实现方法
2015/01/15 Javascript
jQuery实现个性翻牌效果导航菜单的方法
2015/03/09 Javascript
javascript十六进制及二进制转化的方法
2015/05/06 Javascript
JS实现的表格操作类详解(添加,删除,排序,上移,下移)
2015/12/22 Javascript
详解AngularJS 模态对话框
2016/04/07 Javascript
使用Object.defineProperty实现简单的js双向绑定
2016/04/15 Javascript
使用jQuery卸载全部事件的思路详解
2017/04/03 jQuery
小程序api实现promise封装过程解析
2019/11/21 Javascript
一个小示例告诉你Python语言的优雅之处
2014/07/04 Python
python查询mysql中文乱码问题
2014/11/09 Python
python使用PIL模块实现给图片打水印的方法
2015/05/22 Python
使用Python对IP进行转换的一些操作技巧小结
2015/11/09 Python
Pycharm编辑器技巧之自动导入模块详解
2017/07/18 Python
利用 python 对目录下的文件进行过滤删除
2017/12/27 Python
Python 循环语句之 while,for语句详解
2018/04/23 Python
Python openpyxl模块原理及用法解析
2020/01/19 Python
python中的socket实现ftp客户端和服务器收发文件及md5加密文件
2020/04/01 Python
基于python计算滚动方差(标准差)talib和pd.rolling函数差异详解
2020/06/08 Python
纯CSS3实现的阴影效果
2014/12/24 HTML / CSS
水上运动奥特莱斯:Wasterports Outlet
2018/08/08 全球购物
美国轮胎网站:Priority Tire
2018/11/28 全球购物
外语专业毕业生个人的自荐信
2013/11/19 职场文书
校班主任推荐信范文
2013/12/03 职场文书
高中学生期末评语
2014/04/25 职场文书
环卫工作汇报材料
2014/10/28 职场文书
2014年幼儿园教师工作总结
2014/11/08 职场文书
2015年共青团工作总结
2015/05/15 职场文书
导游词之井冈山
2019/11/20 职场文书
Pycharm 如何设置HTML文件自动补全代码或标签
2021/05/21 Python
Java基础之this关键字的使用
2021/06/30 Java/Android