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的session cookie错误
Aug 09 PHP
PHP 模拟$_PUT实现代码
Mar 15 PHP
使用VisualStudio开发php的图文设置方法
Aug 21 PHP
PHP Undefined index报错的修复方法
Jul 17 PHP
域名和cookie问题(域名后缀)
Oct 10 PHP
php和jquery实现地图区域数据统计展示数据示例
Feb 12 PHP
ThinkPHP3.2.2的插件控制器功能简述
Jul 09 PHP
php快速排序原理与实现方法分析
May 26 PHP
PHP利用Cookie设置用户30分钟未操作自动退出功能
Jul 03 PHP
PHP学习笔记之session
May 06 PHP
laravel5 Eloquent 实现事务方式
Oct 21 PHP
微信小程序结合ThinkPHP5授权登陆后获取手机号
Nov 23 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
使用MaxMind 根据IP地址对访问者定位
2006/10/09 PHP
推荐Discuz!5的PHP代码高亮显示与实现可运行代码
2007/03/15 PHP
flash用php连接数据库的代码
2011/04/21 PHP
php实现的SESSION类
2014/12/02 PHP
php实现html标签闭合检测与修复方法
2015/07/09 PHP
Javascript实现重力弹跳拖拽运动效果示例
2013/06/28 Javascript
鼠标移入移出事件改变图片的分辨率的两种方法
2013/12/17 Javascript
IE6下javasc#ipt:void(0) 无效的解决方法
2013/12/23 Javascript
js触发onchange事件的方法说明
2014/03/08 Javascript
JS 弹出层 定位至屏幕居中示例
2014/05/21 Javascript
node.js中的fs.realpathSync方法使用说明
2014/12/16 Javascript
非常实用的12个jquery代码片段
2015/11/02 Javascript
JavaScript事件学习小结(五)js中事件类型之鼠标事件
2016/06/09 Javascript
js基于cookie记录来宾姓名的方法
2016/07/19 Javascript
AngularJS实现DOM元素的显示与隐藏功能
2016/11/22 Javascript
原生js实现鼠标跟随效果
2017/02/28 Javascript
Vue组件库发布到npm详解
2018/02/17 Javascript
Echarts地图添加引导线效果(labelLine)
2019/09/30 Javascript
Vue解决移动端弹窗滚动穿透问题
2020/12/15 Vue.js
Vue看了就会的8个小技巧
2021/01/21 Vue.js
[01:16]DOTA2小知识课堂 Ep.03 芒果树无伤肉山
2019/12/05 DOTA
Python扫描IP段查看指定端口是否开放的方法
2015/06/09 Python
Python 移动光标位置的方法
2019/01/20 Python
Python for循环及基础用法详解
2019/11/08 Python
在python中使用nohup命令说明
2020/04/16 Python
python用Configobj模块读取配置文件
2020/09/26 Python
HTML5视频播放插件 video.js介绍
2018/09/29 HTML / CSS
美国顶级奢侈茶:Mighty Leaf Tea(美泰茶)
2016/11/26 全球购物
党校培训自我鉴定
2014/02/01 职场文书
党员学习群众路线教育实践活动对照检查材料
2014/09/23 职场文书
机关干部个人对照检查材料思想汇报
2014/09/28 职场文书
辣妈辣妹观后感
2015/06/10 职场文书
安全生产标语口号
2015/12/26 职场文书
医务人员岗前培训心得体会
2016/01/08 职场文书
golang中切片copy复制和等号复制的区别介绍
2021/04/27 Golang
Oracle锁表解决方法的详细记录
2022/06/05 Oracle