首先,咱們須要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下的擴展模塊源代碼,不少東西均可以參考的。