开发PHP扩展模块

首先,咱们须要PHP源码包,若是没有就下一个吧,反正很近,就 http://www.php.net了。:Dphp

Linux/BSD下的步骤html

[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。这些子目录包含了编译扩展模块必要的头文件。mysql

[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下用的。sql

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

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

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

[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.m四、php_myext.h、myext.c、myext.php。至于其余文件我就得考虑了。框架

根据提示,咱们作以下操做。ide

[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下的扩展模块源代码,不少东西均可以参考的。

 
相关文章
相关标签/搜索