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