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执行速度全攻略(下)
Oct 09 PHP
PHP开发负载均衡指南
Jul 17 PHP
PHP手机号码归属地查询代码(API接口/mysql)
Sep 04 PHP
腾讯微博提示missing parameter errorcode 102 错误的解决方法
Dec 22 PHP
PIGCMS 如何关闭聊天机器人
Feb 12 PHP
php实现字符串首字母转换成大写的方法
Mar 17 PHP
php约瑟夫问题解决关于处死犯人的算法
Mar 23 PHP
PHP的几个常用加密函数
Feb 03 PHP
Yii2简单实现多语言配置的方法
Jul 23 PHP
php使用ftp实现文件上传与下载功能
Jul 21 PHP
搭建自己的PHP MVC框架详解
Aug 16 PHP
Laravel框架实现简单的学生信息管理平台案例
May 07 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
php 表单验证实现代码
2009/03/10 PHP
PHP架构及原理知识点详解
2019/12/22 PHP
php查看一个变量的占用内存的实例代码
2020/03/29 PHP
CSS+JS构建的图片查看器
2006/07/22 Javascript
JQuery index()方法使用代码
2010/06/02 Javascript
jquery配合css简单实现返回顶部效果
2013/09/30 Javascript
Jquery实现自定义tooltip示例代码
2014/02/12 Javascript
JavaScript基于对象去除数组重复项的方法
2016/10/09 Javascript
AngularJs表单验证实例代码解析
2016/11/29 Javascript
angularjs中ng-bind-html的用法总结
2017/05/23 Javascript
Vue中mintui的field实现blur和focus事件的方法
2018/08/25 Javascript
webstorm中配置Eslint的两种方式及差异比较详解
2018/10/19 Javascript
Vue CLI3.0中使用jQuery和Bootstrap的方法
2019/02/28 jQuery
vue使用Proxy实现双向绑定的方法示例
2019/03/20 Javascript
在Vue 中实现循环渲染多个相同echarts图表
2020/07/20 Javascript
Vue实现导航栏菜单
2020/08/19 Javascript
python批量导出导入MySQL用户的方法
2013/11/15 Python
Python中使用HTMLParser解析html实例
2015/02/08 Python
python matplotlib中文显示参数设置解析
2017/12/15 Python
python使用jieba实现中文分词去停用词方法示例
2018/03/11 Python
Python利用openpyxl库遍历Sheet的实例
2018/05/03 Python
python获取网络图片方法及整理过程详解
2019/12/20 Python
Pyinstaller 打包发布经验总结
2020/06/02 Python
详解python方法之绑定方法与非绑定方法
2020/08/17 Python
使用CSS3实现一个3D相册效果实例
2016/12/03 HTML / CSS
俄罗斯EPL钻石珠宝店:ЭПЛ
2019/10/22 全球购物
请用Java实现列出某个目录下的所有文件
2013/09/23 面试题
简历中求职的个人自我评价
2013/12/03 职场文书
寒假思想汇报
2014/01/10 职场文书
甜点店创业计划书
2014/01/27 职场文书
政法学院毕业生求职信
2014/02/28 职场文书
优秀的个人求职信范文
2014/05/09 职场文书
房地产销售员岗位职责
2015/04/11 职场文书
回复函范文
2015/07/14 职场文书
团队拓展训练感想
2015/08/07 职场文书
MySQL中distinct与group by之间的性能进行比较
2021/05/26 MySQL