45fan.com - 路饭网

搜索: 您的位置主页 > 电脑频道 > 电脑教程 > 阅读资讯:如何开发PHP扩展模块?

如何开发PHP扩展模块?

2016-09-04 15:35:38 来源:www.45fan.com 【

如何开发PHP扩展模块?

首先,我们需要PHP源码包,如果没有就下一个吧,反正很近,就 http://www.php.net了。:D

Linux/BSD下的步骤

[yingyuan@research src]$ pwd
/home/yingyuan/data1/src
[yingyuan@research src]$ ls
php-4.3.4.tar.gz
[yingyuan@research src]$ tar zxvf php-4.3.4.tar.gz
...
[yingyuan@research src]$ cd php-4.3.4

现在我们到了PHP源代码根目录,下文简称为$PHP_SRC_HOME。
仔细看看,这里有这么几个子目录是需要注意的:main, TSRM, Zend。这些子目录包含了编译扩展模块必要的头文件。

[yingyuan@research php-4.3.4]$ cd ext
[yingyuan@research ext]$ ls
... ext_skel ext_skel_win32.php ...

这个目录有很多子目录,每个子目录都是PHP的一个扩展模块。此外还有两个文件:ext_skel是一个shell脚本,运行它能生成PHP扩展模块的框架;ext_skel_win32.php,用来生成Windows下的PHP扩展模块框架。偶心中窃喜,ext_skel_win32.php,哈,开发Windows下的PHP扩展模块变得如此Easy。话虽如此,可是别忘了装CygWin(http://www.cygwin.com/)这个胖的可爱的小助理。像我这样心疼时间的人当然不会装了,所以通常我是在Linux/BSD下用ext_skel生成框架,然后拷贝到Windows下用的。

诸位,我们开始干活了。先看看我们在哪里:

[yingyuan@research ext]$ pwd
/home/yingyuan/data1/src/php-4.3.4/ext

假设我们要写一个很恢宏的PHP扩展模块,模块名叫 myext,则运行如下命令:

[yingyuan@research ext]$ ./ext_skel --extname=myext      
Creating directory myext
Creating basic files: config.m4 .cvsignore myext.c php_myext.h CREDITS EXPERIMENTAL tests/001.phpt myext.php [done].
To use your new extension, you will have to execute the following steps:
1. $ cd ..
2. $ vi ext/myext/config.m4
3. $ ./buildconf
4. $ ./configure --[with|enable]-myext
5. $ make
6. $ ./php -f ext/myext/myext.php
7. $ vi ext/myext/myext.c
8. $ make
Repeat steps 3-6 until you are satisfied with ext/myext/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.

根据提示,ext_skel替我们生成了模块myext的骨架:目录myext, 目录myext下的文件config.m4、php_myext.h、myext.c、myext.php。至于其他文件我就得考虑了。

根据提示,我们做如下操作。

[yingyuan@research ext]$ cd ..
[yingyuan@research php-4.3.4]$ vi ext/myext/config.m4

关于m4文件的撰写说明,这里没空共享给各位了,感兴趣可以上 http://www.gnu.org/software/m4/manual/index.html 瞧瞧。

这里有必要说明一下:
PHP编译的时候要激活某个扩展模块,有两种方式,--with-xxxx和--enable-xxxx。差别在于前者可以引用外部相关文件,比如--with-mysql=/usr/local/mysql等等,而后者不能。这要根据你的需要,比如你要写一个xml parser扩展,想在你的扩展代码中引用外部系统的libxml,那么为了保证你的代码总是能成功找到必要的libxml文件,就可以用--with-xxxx方式,让用户在编译的时候指定libxml文件位置。
我们这里用--enable-xxxx吧,因为我们的myext确实没什么好引用的。

找到这么几行:

dnl PHP_ARG_ENABLE(myext, whether to enable myext support,
dnl Make sure that the comment is aligned:
dnl [ --enable-myext      Enable myext support])
if test "$PHP_MYEXT" != "no"; then
 dnl Write more examples of tests here...
...

改成:

PHP_ARG_ENABLE(myext, whether to enable myext support,
[ --enable-myext      Enable myext support])
if test "$PHP_MYEXT" == "yes"; then
 dnl Write more examples of tests here...
...

首先需要告诉PHP自动编译系统不要对我们的扩展模块视而不见,然后还需要在用户明确要求enable我们的扩展模块时才编译。这就是以上修改的原因。

接着往下走:

[yingyuan@research php-4.3.4]$ ./buildconf
You should not run buildconf in a release package.
use buildconf --force to override this check.

系统抱怨说发行版本不能运行 buildconf,嘿嘿,我们强制运行:

[yingyuan@research php-4.3.4]$ ./buildconf --force
[yingyuan@research php-4.3.4]$ ./configure --help | grep myext
 --enable-myext      Enable myext support

从这个输出可以看到我们的扩展模块已经可用。

[yingyuan@research php-4.3.4]$ ./configure --enable-myext
...
[yingyuan@research php-4.3.4]$ make
...
[yingyuan@research php-4.3.4]$ ./sapi/cli/php -f ext/myext/myext.php 
Functions available in the test extension:
confirm_myext_compiled

Congratulations! You have successfully modified ext/myext/config.m4. 
Module myext is now compiled into PHP.

至此我们的demo函数已经奏效,接下来听你们提问了:

Q1:我一定要make整个PHP代码包才可以make我的扩展模块吗?
A1:不用。你甚至不用修改config.m4文件。方法是手工编译扩展模块:
切换到目录$PHP_SRC_HOME/ext
cc -fpic -DCOMPILE_DL=1 -DCOMPILE_DL_module_name -I/usr/local/include -I. -I.. -I../Zend -I../main -I../TSRM -c -o
cc -shared -L/usr/local/lib -rdynamic -o

本例中,

[yingyuan@research php-4.3.4]$ cd ext
[yingyuan@research ext]$ cc -fpic -DCOMPILE_DL=1 -DCOMPILE_DL_MYEXT -I/usr/local/include /
-I. -I.. -I../Zend -I../main -I../TSRM -c -o myext/myext.o myext/myext.c
[yingyuan@research ext]$ cc -shared -L/usr/local/lib -rdynamic -o myext/myext.so myext/myext.o

Q2:怎样为我的扩展模块生成GUN AutoMake兼容的自动编译文件
A2:利用$PHP_SRC_HOME/scrīpts/phpize。其实$PHP_SRC_HOME/scrīpts/下面还有别的有意思的东西。:D

Q3:怎样用C++写PHP扩展模块
A3:这涉及到C和C++的名称转换问题,需要对C定义的头文件用extern "C"包围起来,本文不提供更详细的信息。

Windows下的步骤

我们需要前面所说的PHP源代码包,还需要php4ts.lib。后者可以在PHP的Windows安装包中找到。这里我们谈谈用VC 6如何开发PHP扩展模块。不要有恐惧心理,微软让事情变得更简单而不是更复杂。
我们新建一个Win32 Dylamic-Link Library项目myext,选择Empty Project。然后把ext_skel生成的两个文件php_myext.h、myext.c添加到项目中,做如下设定:

打开菜单项 Build >> Set Active Configuration...,这里有两个项可供选择:Win32 Release和Win32 Debug,我们这里选择Win32 Release。

打开菜单项 Tools >> Options,选择Directories属性页.在这里可以对头文件和库文件的搜索路径进行设置.
在Show directories for 下拉列表中选择Library files, 把php4ts.lib所在的目录添加进去.比如C:/PHP/PHP-4.3.11.
在Show directories for 下拉列表中选择Include files,把PHP头文件所在的路径加上,比如:
C:/PHP/PHP-4.3.4
C:/PHP/PHP-4.3.4/main
C:/PHP/PHP-4.3.4/TSRM
C:/PHP/PHP-4.3.4/Zend

打开菜单项 Project >> Settings...,选择C/C++属性页。
在Category下拉列表中选择Code Generation,在Use run-time library下拉列表中选择Multithreaded DLL(对应于Win32 Release版本)或者Debug Multithreaded DLL(对应于Win32 Debug版本)。
在Category下拉列表中选择Preprocessor,在Preprocessor defines里添加 ZEND_DEBUG=0,COMPILE_DL_SIPLOOKUP,ZTS=1,ZEND_WIN32,PHP_WIN32。如果你在调试你的工程,可把ZEND_DEBUG设置为1.这里也可以在Additional include directories设置搜索头文件,不过因为我们已经在以上的步骤设置了,就没有必要了。最后我们在Project Options中添加选项 /Tc,这告诉编译器把我们的源文件当C程序处理。

在菜单项 Project >> Settings...中,选择Link属性页。
在Object/library modules中把php4ts.lib添加进去。
然后就可以进行Build,生成我们的DLL文件。如果有错误不用着急,相信自己,相信Google。^_^

几点建议

PHP手册是开发扩展模块最好的教材,如果有心于斯就一定要看看,这个不能偷懒了;
PHP扩展模块开发网站 http://pecl.php.net 可以去看看;
如果不知道该如何着手,比如不知道怎样创建Resource,或者从函数中返回值,最快的方式就是翻翻$PHP_SRC_HOME/ext下的扩展模块源代码,很多东西都可以参考的。

 

本文地址:http://www.45fan.com/dnjc/72298.html
Tags: PHP 开发 扩展
编辑:路饭网
关于我们 | 联系我们 | 友情链接 | 网站地图 | Sitemap | App | 返回顶部