Linux下php扩展模块开发

news/2024/7/10 17:08:48 标签: php, 扩展, linux, module, function, extension

项目做了快半年了,关于php扩展模块开发,从完全不懂到边查资料边摸索,到现在的灵活运用,其间也经历了不少的困惑期,在此以文章记录,希望对有同样需求的人起到一定的帮助作用。

一. 生成一个简单的php extension

我们需要两个目录:php src,php bin,到网上下载一个php源码包,解压,安装。

php的解压目录记为 phpsrc(如:/home/src/php-4.4.4) ,安装目录记为 phpbin(如 /usr/local/php
在shell下输入(以后遇到有shell的地方我就用#开头,不另陈述)

# cd phpsrc/ext
# ./ext_skel --extname=test_module

Creating directory test_module
Creating basic files: config.m4 .cvsignore test_module.c php_test_module.h CREDITS EXPERIMENTAL tests/001.phpt test_module.php [done].

To use your new extension, you will have to execute the following steps:

1. $ cd ..
2. $ vi ext/test_module/config.m4
3. $ ./buildconf
4. $ ./configure --[with|enable]-test_module
5. $ make
6. $ ./php -f ext/test_module/test_module.php
7. $ vi ext/test_module/test_module.c
8. $ make

Repeat steps 3-6 until you are satisfied with ext/test_module/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.

系统自动生成 test_module文件夹;接下来我们要修改几个文件:config.m4, test_module.c,php_test_module.h, 如下:

1) 修改config.m4

# cd test_module
# vi config.m4

找到这几行

dnl PHP_ARG_ENABLE(test_module, whether to enable test_module support,

dnl Make sure that the comment is aligned:
dnl [ --enable-test_module Enable test_module support])
去掉这几行前面的dnl,改为
PHP_ARG_ENABLE(test_module, whether to enable test_module support,

Make sure that the comment is aligned:
[ --enable-test_module Enable test_module support])

这样以后编译php时,./configure后面加 --enable-test_module 就可以加载你的php模块了!

(接下来的2)你可以做也可以不做,直接跳到第4步也可以运行。)

2) 修改test_module.c,输出自己想要的东西

# vi test_module.c


找到这段
PHP_FUNCTION(confirm_test_module_compiled)
{
char *arg = NULL;
int arg_len, len;
char string[256];

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
return;
}

len = sprintf(string, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "test_module", arg);
RETURN_STRINGL(string, len, 1);
}
改为:
PHP_FUNCTION(confirm_test_module_compiled)
{
zend_printf("This is a test module !");
}

3)编译链接

# cd phpsrc/ext
# cc -fpic -DCOMPILE_DL_TEST_MODULE=1 -I/usr/local/include -I. -I../main -I.. -I../TSRM -I../Zend -c -o test_module/test_module.o test_module/test_module.c

执行完之后会在 目录下生成一个test_module.o文件,接下来连接:

# cc -shared -L/usr/local/lib -rdynamic -o test_module/test_module.so test_module/test_module.o

4)测试:

有两种途径可以测试你的扩展模块是否正确,一是在phpbin目录下运行test.php, 二是在web browser上运行test.php(如果已经安装apache等web服务器的话)。

这里采用phpbin测试,不需要任何web服务器。

拷贝test_module.so到phpbin的相应目录下

(如果不知道是哪个目录,或者没有拷贝到正确的位置,在运行的时候出错信息里会指出应该在什么路径。)
# mkdir -p phpbin/lib/php/extensions/ (其实这个目录就是看你php.ini里设置extension_dir了)
# cp test_module/test_module.so phpbin/lib/php/extensions/

phpbin目录下新建一个test.php文件,在里面写入


dl("test_module.so");

//调用函数

test_module();

?>

phpbin目录下运行
执行./php –q test.php,如果过程无误,将会显示:
This is a test module !

测试成功,接下来我们可以往扩展模块中添加自己的函数,实现自己的功能啦。


二. 向扩展模块中添加函数

php扩展模块中添加函数,只需要修改test_module.c和php_test_module.h。

比如要向扩展模块中添加一个函数sayhello(),我们需要做以下工作:

1) 修改 php_test_module.h 添加函数声明
在文件中PHP_FUNCTION(confirm_my_module_compiled);一行前面添加下面的代码
PHP_FUNCTION(say_hello);
保存文件退出

2) 修改 test_module.c

function_entry中添加函数的entry:

function_entry my_module_functions[] = {
PHP_FE(say_hello, NULL) /* ß添加着一行代码 */
PHP_FE(confirm_my_module_compiled, NULL) /* For testing, remove later. */
{NULL, NULL, NULL} /* Must be the last line in my_module_functions[] */
};

在文件的最后添加函数的实现:
PHP_FUNCTION(say_hello)
{
zend_printf("hello world/n");
}
保存文件退出

3)重新编译链接,生成新的.so文件。

# cd phpsrc/ext
# cc -fpic -DCOMPILE_DL_TEST_MODULE=1 -I/usr/local/include -I. -I../main -I.. -I../TSRM -I../Zend -c -o test_module/test_module.o test_module/test_module.c

执行完之后会在 目录下生成一个test_module.o文件,接下来连接:

# cc -shared -L/usr/local/lib -rdynamic -o test_module/test_module.so test_module/test_module.o


三. 调用第三方C/C++库

在PHP扩展模块中调用第三方的C/C++库,与普通的C/C++程序调用C/C++库一样,只要把库文件的位置放对就可以了。下面举例说明:

1. 调用动态库a.so

需要的文件,a.so,a.h(a.h主要做数据类型声明和入口函数声明),都放在 test_module目录下。

调用a.so:

1) 在test_module.c的开头添加a.h:

#include "php.h

#include "php_ini.h"
#include "a.h"
添加了头文件后,可以在test_module.c的函数中调用a.so的函数接口。

2) 重新编译链接,链接时加入a.so:

# cd phpsrc/ext
# cc -fpic -DCOMPILE_DL_TEST_MODULE=1 -I/usr/local/include -I. -I../main -I.. -I../TSRM -I../Zend -c -o test_module/test_module.o test_module/test_module.c

执行完之后会在 目录下生成一个test_module.o文件,接下来连接:

# cc -shared -L/usr/local/lib -rdynamic -o test_module/test_module.so test_module/test_module.o test_module/a.so

[如果a.so内部实现是C++,链接时还应该加入参数 –lstdc++,即:

# cc –shared –lstdc++ -L/usr/local/lib -rdynamic -o test_module/test_module.so test_module/test_module.o test_module/a.so

]

3) 测试test_module.so时,把test_module.so和a.so都拷贝到phpbin/lib/php/extensions/下。

2. 调用静态库a.a

需要的文件,a.so,a.h(a.h主要做数据类型声明和入口函数声明),都放在 test_module目录下。

调用a.a:

1) 和2)都与调用a.so相同。

3) 测试test_module.so时,把test_module.so拷贝到phpbin/lib/php/extensions/下,a.a不需要。


http://www.niftyadmin.cn/n/1790531.html

相关文章

Laravel一些常用命令整理

自动创建项目 laravel new || laravel new xxx || composer create-project --prefer-dist laravel/laravel blogcomposer create-project --prefer-dist laravel/laravel blogcomposer global require “laravel/installer”laravel new blog 安装组件 composer install 刷新组…

雅虎前端优化14准则

1.尽可能使用少的HTTP请求 Make fewer HTTP requests; 这个是很重要的一条&#xff0c;具体措施是使用Image maps 和Inline Images&#xff1b;合并CSS和脚本代码。比如对于Image Maps (服务器端)server-side <a href"navbar.cgi"> <img ismap src&quo…

lua笔记

print(2^2) --4 print(3^4) --27 -- 等于pow(3, 4) cmd交互 通过 lua -i proj 打开的文件, 可以用 dofiles "xx.lua" (文件在IDE编辑)重新载入, 热更? lua -e "string to code" -l loadlib -i cmd cmd/解释器参数args: [-3] "…

Android中使用libjpeg-turbo进行图片质量压缩过程记录

2019独角兽企业重金招聘Python工程师标准>>> 项目开发过程中发现Android的质量压缩算法在图片过大&#xff0c;色彩丰富的前提下&#xff0c;压缩的性能不是特别好&#xff0c;经过调查发现Android底层实现使用Skia引擎&#xff0c;封装了了libjpeg图像库。为了适配…

设计模式之刘伟老师文章学习记录-------------里氏代换原则

里氏代换原则告诉我们&#xff0c;在软件中将一个基类对象替换成它的子类对象&#xff0c;程序将不会产生任何错误和异常&#xff0c;反过来则不成立&#xff0c;如果一个软件实体使用的是一个子类对象的话&#xff0c;那么它不一定能够使用基类对象。例如&#xff1a;我喜欢动…

Web开发人员应当知道的15个开源项目

如今&#xff0c;构建网站和开发Web应用程序已经不仅要求开发人员是一名优秀的程序员&#xff0c;更需要聪明的程序员。这也就是说&#xff0c;在可能的情况下&#xff0c;重复使用已有的代码和应用程序&#xff0c;而不是自己重头开始。 开源由来已久&#xff0c;并且很多网站…

京东Vue组件库NutUI 2.0发布:将支持跨平台!

NutUI 是一套来自京东用户体验设计部&#xff08;JDC&#xff09;前端开发部的移动端 Vue 组件库&#xff0c;NutUI 1.0 版本于 2018 年发布。据不完全统计&#xff0c;目前在京东至少有30多个 web 项目正在使用 NutUI。 经过一段时间紧锣密鼓的开发&#xff0c;近期&#xff0…

2017 济南综合班 Day 5

毕业考试 (exam.cpp/c/pas) (1s/256M) 问题描述 快毕业了&#xff0c;Barry希望能通过期末的N门考试来顺利毕业。如果他的N门考试平均分能够达到V分&#xff0c;则他能够成功毕业。现在已知每门的分数不能够超过R&#xff1b;他的第i门考试目前得分为Ai&#xff0c;如果想要在这…