PHP扩展编写示例
1、生成描述文件,包含对函数等的定义
[chengyi@localhost php-extension]$ cat hello_cy.def
string self_concat(string str, int n);
2、进入PHP源码的ext目录
[chengyi@localhost ext]$ pwd
/home/chengyi/centos_soft_install/php-5.2.5/ext
3、查看ext_skel的帮助,我们主要用到的是 --extname=module 定义将要生成的模块名称; --proto=file 指向刚才的描述函数定义的文件。
[chengyi@localhost ext]$ ./ext_skel --help
./ext_skel --extname=module [--proto=file] [--stubs=file] [--xml[=file]]
[--skel=dir] [--full-xml] [--no-help]
--extname=module module is the name of your extension
--proto=file file contains prototypes of functions to create
--stubs=file generate only function stubs in file
--xml generate xml documentation to be added to phpdoc-cvs
--skel=dir path to the skeleton directory
--full-xml generate xml documentation for a self-contained extension
(not yet implemented)
--no-help don't try to be nice and create comments in the code
and helper functions to test if the module compiled
4、执行ext_skel,生成空模块
[chengyi@localhost ext]$ ./ext_skel --extname=hello_cy --proto=/home/chengyi/test-all/php-extension/hello_cy.def
Creating directory hello_cy
awk: /home/chengyi/centos_soft_install/php-5.2.5/ext/skeleton/create_stubs:56: warning: escape sequence `/|' treated as plain `|'
Creating basic files: config.m4 config.w32 .cvsignore hello_cy.c php_hello_cy.h CREDITS EXPERIMENTAL tests/001.phpt hello_cy.php [done].
To use your new extension, you will have to execute the following steps:
1. $ cd ..
2. $ vi ext/hello_cy/config.m4
3. $ ./buildconf
4. $ ./configure --[with|enable]-hello_cy
5. $ make
6. $ ./php -f ext/hello_cy/hello_cy.php
7. $ vi ext/hello_cy/hello_cy.c
8. $ make
Repeat steps 3-6 until you are satisfied with ext/hello_cy/config.m4 and
step 6 confirms that your module is compiled into PHP. Then, start writing
code and repeat the last two steps as often as necessary.
5、将生成的空模块mv到自己的目录下去(这里我们没有按照上面ext_skel的说明来做)
[chengyi@localhost ext]$ mv hello_cy/ ~/test-all/php-extension/
6、进入到空模块下,查看都生成了哪些文件
[chengyi@localhost hello_cy]$ ls -p
config.m4 config.w32 CREDITS EXPERIMENTAL hello_cy.c hello_cy.php php_hello_cy.h tests/
可以看到,有一个tests目录。
7、修改config.m4文件,打开编译选项
PHP_ARG_ENABLE(hello_cy, whether to enable hello_cy support,
[ --enable-hello_cy Enable hello_cy support])
if test "$PHP_HELLO_CY" != "no"; then
AC_DEFINE(HAVE_HELLO_CY, 1, [Whether you have Hello World])
PHP_NEW_EXTENSION(hello_cy, hello_cy.c, $ext_shared)
fi
8、执行phpize生成更多文件,为编译做准备
[chengyi@localhost hello_cy]$ phpize
Configuring for:
PHP Api Version: 20041225
Zend Module Api No: 20060613
Zend Extension Api No: 220060519
[chengyi@localhost hello_cy]$ ls
acinclude.m4 build config.m4 configure.in EXPERIMENTAL install-sh missing run-tests.php
aclocal.m4 config.guess config.sub config.w32 hello_cy.c ltmain.sh mkinstalldirs tests
autom4te.cache config.h.in configure CREDITS hello_cy.php Makefile.global php_hello_cy.h
9、开始编译
./configure --enable-hello_cy
make
make test
sudo make install (有时php ext路径不对,就手工cp过去)
10、测试
[chengyi@localhost hello_cy]$ php hello_cy.php
Functions available in the test extension:
confirm_hello_cy_compiled
self_concat
Congratulations! You have successfully modified ext/hello_cy/config.m4. Module hello_cy is now compiled into PHP.
11、如果想要重新获取到一个干净的目录,执行 phpize --clean
12、将扩展加载,修改php.ini文件
如果不确定php.ini的位置,执行如下:
[chengyi@localhost hello_cy]$ php -i|grep "php.ini"
Configuration File (php.ini) Path => /usr/local/php/lib
Loaded Configuration File => /usr/local/php/lib/php.ini
可以看到,该文件在/usr/local/php/lib/php.ini。
在该文件中添加: extension=hello_cy.so
然后重启apache,如果需要在web端执行的话(如果仅在本地脚本执行,则不用重启apache,因为压根没关系)。
-----------------------------------------------------
探求代码为什么这么写呢?
首先要声明,探求这些只能去PHP的源码看了。源码中比较重要的两个目录是main和Zend。
1、PHP_FUNCTION(self_concat){} 是个什么东西?为什么要用它来定义我们的函数呢?
我们在里面找寻PHP_FUNCTION的定义,在main/下:
php.h:#define PHP_FUNCTION ZEND_FUNCTION
然后我们去Zend/目录下,发现了 ZEND_FUNCTION的定义:
zend_API.h:#define ZEND_FUNCTION(name) ZEND_NAMED_FUNCTION(ZEND_FN(name))
然后继续由 ZEND_NAMED_FUNCTION, ZEND_FN的定义追查下去得到: void zif_name(INTERNAL_FUNCTION_PARAMETERS)
再看INTERNAL_FUNCTION_PARAMETERS (其实php源码下都有tags,直接ctrl+]就可以跟踪定义了),得到完整的函数定义:
void zif_name(int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC); // 其实我还蛮好奇这几个参数为什么要这样设置的,等有空去仔细看源码
2、怎样返回值?
我们经常使用的返回值的宏是 RETURN_STRING之类的,去Zend/下找它的定义:
#define RETURN_STRING(s, duplicate) { RETVAL_STRING(s, duplicate); return; }
#define RETVAL_STRING(s, duplicate) ZVAL_STRING(return_value, s, duplicate)
可以看出,是给函数定义的参数return_value赋值了,然后估计是由PHP内部的机制,直接把return_value返回。
PHP扩展编写示例的更多相关文章
- 老李推荐:第3章3节《MonkeyRunner源码剖析》脚本编写示例: MonkeyImage API使用示例 1
老李推荐:第3章3节<MonkeyRunner源码剖析>脚本编写示例: MonkeyImage API使用示例 在上一节的第一个“增加日记”的示例中,我们并没有看到日记是否真的增加成功 ...
- 老李推荐: 第3章1节《MonkeyRunner源码剖析》脚本编写示例: MonkeyRunner API使用示例
老李推荐: 第3章1节<MonkeyRunner源码剖析>脚本编写示例: MonkeyRunner API使用示例 MonkeyRunner这个类可以说是编写monkeyrunner脚 ...
- PHP扩展编写、PHP扩展调试、VLD源码分析、基于嵌入式Embed SAPI实现opcode查看
catalogue . 编译PHP源码 . 扩展结构.优缺点 . 使用PHP原生扩展框架wizard ext_skel编写扩展 . 编译安装VLD . Debug调试VLD . VLD源码分析 . 嵌 ...
- 第3章3节《MonkeyRunner源码剖析》脚本编写示例: MonkeyImage API使用示例(原创)
天地会珠海分舵注:本来这一系列是准备出一本书的,详情请见早前博文“寻求合作伙伴编写<深入理解 MonkeyRunner>书籍“.但因为诸多原因,没有如愿.所以这里把草稿分享出来,所以错误在 ...
- 第3章2节《MonkeyRunner源码剖析》脚本编写示例: MonkeyDevice API使用示例(原创)
天地会珠海分舵注:本来这一系列是准备出一本书的,详情请见早前博文“寻求合作伙伴编写<深入理解 MonkeyRunner>书籍“.但因为诸多原因,没有如愿.所以这里把草稿分享出来,所以错误在 ...
- 第3章1节《MonkeyRunner源码剖析》脚本编写示例: MonkeyRunner API使用示例(原创)
天地会珠海分舵注:本来这一系列是准备出一本书的,详情请见早前博文“寻求合作伙伴编写<深入理解 MonkeyRunner>书籍“.但因为诸多原因,没有如愿.所以这里把草稿分享出来,所以错误在 ...
- Chrome浏览器扩展开发系列之十九:扩展开发示例
翻译总结了这么多的官网内容,下面以一款博主开发的“沪深股票价格变化实时追踪提醒”软件为例,介绍Chrome浏览器扩展程序的开发,开发环境为Eclipse IDE+Chrome Browser. “沪深 ...
- GDAL库进度信息编写示例
GDAL进度信息编写 GDAL库中的算法以及读写数据的时候一般都会提供两个与进度信息相关的参数,下面分别进行描述: GDALProgressFunc pfnProgress void * pProgr ...
- Slickflow.NET 开源工作流引擎快速入门之三: 简单或分支流程代码编写示例
前言:对于急切想了解引擎功能的开发人员,在下载版本后,就想尝试编写代码,完成一个流程的开发和测试.本文试图从请假流程,或分支模式来快速了解引擎代码的编写. 1. 创建或分支流程图形 或分支流程是常见的 ...
随机推荐
- JavaScript中的作用域与函数和变量声明的提升
var foo = 1; function bar() { if (!foo) { var foo = 10; } alert(foo); } bar(); ...
- win7 X64可用的单文件IE7 遨游美化版
这个是在深度社区淘来的,哇,才700多Kb,而且里面还集成了很多的功能,在win7 X64下面正常运行.哈哈 分享给大家: http://pan.baidu.com/share/link?uk=171 ...
- 中国地图投影(实现Lambert投影)
一.简介 目前Web地图已经是一个非常普遍的应用,百度地图,高德地图等等极大的方便了我们的生活和学习.本项目主要是在Web完成一个简单的中国地图的绘制,实现Lambert投影. 二.制图源数据信息及来 ...
- Centos搭建PHP5.3.8+Nginx1.0.9+Mysql5.5.17
操作环境 操作系统:Mac Os Lion 虚拟主机:VMware Fusion 虚拟系统:Centos 5.5+ 操作用户:Root 实现目的:搭建LNMP环境. 安装依赖库和开发环境 #依赖库和开 ...
- 代理的使用 一(helloworld级别)
个人理解(估计,半年一年后,在看到这篇文章的时候,会觉得,当时真的弱爆了) 当我们自定义view的时候,比如说view上面有几个按钮,那么我们在别的地方使用这个view的时候,怎么来处理这些点击事件呢 ...
- iOS Core Animation学习总结(3)--动画的基本类型
一. CABasicAnimation (基础动画) 移位: CABasicAnimation *animation = [CABasicAnimation animation]; //keyPath ...
- 判断对象是不是Vector
判断对象是不是数组可以用 var arr:Array = []; trace(arr is Array);//true var vec:Vector.<String> = new Vect ...
- 一篇关于学C++的感想(拿来与大家分享)
学计算机的如果你有耐心看下去,我敢保证这绝对是一种收获 期待爱 大师提醒: 计算机专业不是学编程,而是懂得计算机的工作原理,以及和计算机相关的学科技术.一个高手不必懂得编程,coder是最底层的人物, ...
- java多线程之停止线程
/*1.让各个对象或类相互灵活交流2.两个线程都冻结了,就不能唤醒了,因为根据代码要一个线程活着才能执行唤醒操作,就像玩木游戏3.中断状态就是冻结状态4.当主线程退出的时候,里面的两个线程都处于冻结状 ...
- cannot convert from '_TCHAR *' to 'char *'
Reference: Why can't convert TCHAR* to char* Need to Use Multi-Byte Character Set in project's setti ...