Sunday, July 18, 2010

PHP Extension 的開發環境建立 (Unix-Like方式)

PHP Extension 的開發環境建立 (Unix-Like方式)

有一陣沒寫 php extension,最近試了一下 PHP 5.3.1 ,發覺它的預設有稍微的不一樣。所以重新記錄一下,建立一個PHP extension 的方式與注意事項。這一篇使用 Linux 下開發當範例,大部分的 unix - like 都為相同方式。


1. 下載 PHP Source


phper@debian:/opt/source$ wget http://tw.php.net/get/php-5.3.1.tar.gz/from/tw2.php.net/mirror

2. 解開 PHP Source


phper@debian:/opt/source$ tar zxvf php-5.3.1.tar.gz

3. 編譯 PHP Source:產生 CLI 執行檔和相關開發用檔案(如php-config, phpize),為了減少不必要的模組載入和開發套件的安裝,編譯設定使用 --disable-all 只保留預設的模組。

phper@debian:/opt/source$cd php-5.3.1
phper@debian:/opt/source/php-5.3.1$ ./configure --prefix=/opt/source/php --disable-all
phper@debian:/opt/source/php-5.3.1$ make
phper@debian:/opt/source/php-5.3.1$ make install

4. 將 php.ini 放置到指定的預設路徑

phper@debian:/opt/source/php-5.3.1$ cp php.ini-production /opt/source/php/lib/php.ini


5. 使用靜態方式產生 php 模組

phper@debian:/opt/source/php-5.3.1$ cd ext/

6. 檢視指令說明:


phper@debian:/opt/source/php-5.3.1/ext$ ./ext_skel --help
./ext_skel --extname=module [--proto=file] [--stubs=file] [--xml[=file]] [--skel=dir] [--full-xml] [--no-help]

--extname=module module is the name of your extension
--proto=file file contains prototypes of functions to create
--stubs=file generate only function stubs in file
--xml generate xml documentation to be added to phpdoc-cvs
--skel=dir path to the skeleton directory
--full-xml generate xml documentation for a self-contained extension (not yet implemented)
--no-help don't try to be nice and create comments in the code and helper functions to test if the module compiled


7. 產生 PHP Extension 範例樣版程式碼:使用 --extname 指定 extension 名稱,執行下面指令就會產生相關的程式碼和設定檔。這邊範例使用 my_module 這個名稱。


phper@debian:/opt/source/php-5.3.1/ext$ ./ext_skel --extname=my_module
Creating directory my_module
Creating basic files: config.m4 config.w32 .cvsignore my_module.c php_my_module.h CREDITS EXPERIMENTAL tests/001.phpt my_module.php [done].

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

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

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

上面產生的說明:『3. $./buildconf 』,在不刪除 ./configure 下需使用 ./buildconf --force 強制寫入產生 ./configure 這個檔案


9. 編輯 config.m4:由於開發時用單一編譯 shared module 方式比較單純,所以我們使用這種方式


phper@debian:/opt/source/php-5.3.1/ext/my_module$ vi config.m4

將下面的資訊,將dnl字串移除(dnl為註解)


dnl PHP_ARG_WITH(my_module, for my_module support,
dnl Make sure that the comment is aligned:
dnl [ --with-my_module Include my_module support])

改為

PHP_ARG_WITH(my_module, for my_module support,
Make sure that the comment is aligned:
[ --with-my_module Include my_module support])

並且加上下面這行參數

PHP_SUBST(MY_MODULE_SHARED_LIBADD)

其中MY_MODULE_SHARED_LIBADD 和你使用的 Extension 名稱需相同,如你的 PHP Extension 名稱為 demo ,這邊需改為 DEMO_SHARED_LIBADD。
8. 到模組內,產生 configure


phper@debian:/opt/source/php-5.3.1/ext$cd my_module
phper@debian:/opt/source/php-5.3.1/ext/my_module$ /opt/source/php/bin/phpize

執行phpize 會產生 configure 這個腳本設定檔。

10. 編譯設定

phper@debian:/opt/source/php-5.3.1/ext/my_module$ ./configure --with-php-onfig=/opt/source/php/bin/php-config

11.編譯 Extension,產生 .so 檔案。


phper@debian:/opt/source/php-5.3.1/ext/my_module$ make install
Installing shared extensions: /opt/source/php/lib/php/extensions/no-debug-non-zts-20090626/


12.設定 php.ini

編輯php.ini

phper@debian:/opt/source/php-5.3.1/ext/my_module$ vi /opt/source/php/lib/php.ini

找 extension_dir


;extension_dir


改 (剛剛產生的路徑資訊)


extension_dir="/opt/source/php/lib/php/extensions/no-debug-non-zts-20090626/"


接著找 Dynamic Extensions 在附近加上自己模組的.so檔。


extension=my_module.so

13.執行 PHP CLI:看看是否可以載入剛剛編譯的PHP Extension。


phper@debian:/opt/source/php-5.3.1/ext/my_module$ /opt/source/php/bin/php -m

[PHP Modules]
Core
date
ereg
my_module
pcre
Reflection
SPL
standard

[Zend Modules]

有出現 my_module 這個延伸模組,表示 PHP 執行時有載入。
14. 執行 my_module 內範例程式碼的預設建立函式,confirm_my_module_compiled


是否能被執行。


phper@debian:/opt/source/php-5.3.1/ext/my_module$ /opt/source/php/bin/php my_module.php
Functions available in the test extension:
confirm_my_module_compiled
Congratulations! You have successfully modified ext/my_module/config.m4. Module my_module is now compiled into PHP.

大致開發前的環境如上這樣建立即可,接下來就是程式碼的變化(指Step 7中,『7. $ vi ext/my_module/my_module.c』 如何建立一個 class 與 method 或建立一個 function) ,這部份的文章稍晚再放上來部落格來。

No comments: