Linux下php擴充模組開發

來源:互聯網
上載者:User

項目做了快半年了,關於php的擴充模組開發,從完全不懂到邊查資料邊摸索,到現在的靈活運用,其間也經曆了不少的困惑期,在此以文章記錄,希望對有同樣需求的人起到一定的協助作用。

一. 產生一個簡單的php extension

我們需要兩個目錄:php src,php bin,到網上下載一個php源碼包,解壓,安裝。

php的解壓目錄記為 phpsrc(如:/home/src/php-4.4.4) ,安裝目錄記為 phpbin(如 /usr/local/php)
在shell下輸入(以後遇到有shell的地方我就用#開頭,不另陳述)

# cd phpsrc/ext
# ./ext_skel --extname=test_module

Creating directory test_module
Creating basic files: config.m4 .cvsignore test_module.c php_test_module.h CREDITS EXPERIMENTAL tests/001.phpt test_module.php [done].

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

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

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

系統自動產生 test_module檔案夾;接下來我們要修改幾個檔案:config.m4, test_module.c,php_test_module.h, 如下:

1) 修改config.m4

# cd test_module
# vi config.m4

找到這幾行

dnl PHP_ARG_ENABLE(test_module, whether to enable test_module support,

dnl Make sure that the comment is aligned:
dnl [ --enable-test_module Enable test_module support])
去掉這幾行前面的dnl,改為
PHP_ARG_ENABLE(test_module, whether to enable test_module support,

Make sure that the comment is aligned:
[ --enable-test_module Enable test_module support])

這樣以後編譯php時,./configure後面加 --enable-test_module 就可以載入你的php模組了!

(接下來的2)你可以做也可以不做,直接跳到第4步也可以運行。)

2) 修改test_module.c,輸出自己想要的東西

# vi test_module.c

找到這段
PHP_FUNCTION(confirm_test_module_compiled)
{
char *arg = NULL;
int arg_len, len;
char string[256];

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
return;
}

len = sprintf(string, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "test_module", arg);
RETURN_STRINGL(string, len, 1);
}
改為:
PHP_FUNCTION(confirm_test_module_compiled)
{
zend_printf("This is a test module !");
}

3)編譯連結

# cd phpsrc/ext
# cc -fpic -DCOMPILE_DL_TEST_MODULE=1 -I/usr/local/include -I. -I../main -I.. -I../TSRM -I../Zend -c -o test_module/test_module.o test_module/test_module.c

執行完之後會在 目錄下產生一個test_module.o檔案,接下來串連:

# cc -shared -L/usr/local/lib -rdynamic -o test_module/test_module.so test_module/test_module.o

4)測試:

有兩種途徑可以測試你的擴充模組是否正確,一是在phpbin目錄下運行test.php, 二是在web browser上運行test.php(如果已經安裝apache等web伺服器的話)。

這裡採用phpbin測試,不需要任何web伺服器。

拷貝test_module.so到phpbin的相應目錄下

(如果不知道是哪個目錄,或者沒有拷貝到正確的位置,在啟動並執行時候出錯資訊裡會指出應該在什麼路徑。)
# mkdir -p phpbin/lib/php/extensions/ (其實這個目錄就是看你php.ini裡設定extension_dir了)
# cp test_module/test_module.so phpbin/lib/php/extensions/

在phpbin目錄下建立一個test.php檔案,在裡面寫入

dl("test_module.so");

//調用函數

test_module();

?>

在phpbin目錄下運行
執行./php –q test.php,如果過程無誤,將會顯示:
This is a test module !

測試成功,接下來我們可以往擴充模組中添加自己的函數,實現自己的功能啦。

二. 向擴充模組中添加函數

向php擴充模組中添加函數,只需要修改test_module.c和php_test_module.h。

比如要向擴充模組中添加一個函數sayhello(),我們需要做以下工作:

1) 修改 php_test_module.h 添加函式宣告
在檔案中PHP_FUNCTION(confirm_my_module_compiled);一行前面添加下面的代碼
PHP_FUNCTION(say_hello);
儲存檔案退出

2) 修改 test_module.c

在function_entry中添加函數的entry:

function_entry my_module_functions[] = {
PHP_FE(say_hello, NULL) /* ß添加著一行代碼 */
PHP_FE(confirm_my_module_compiled, NULL) /* For testing, remove later. */
{NULL, NULL, NULL} /* Must be the last line in my_module_functions[] */
};

在檔案的最後添加函數的實現:
PHP_FUNCTION(say_hello)
{
zend_printf("hello world/n");
}
儲存檔案退出

3)重新編譯連結,產生新的.so檔案。

# cd phpsrc/ext
# cc -fpic -DCOMPILE_DL_TEST_MODULE=1 -I/usr/local/include -I. -I../main -I.. -I../TSRM -I../Zend -c -o test_module/test_module.o test_module/test_module.c

執行完之後會在 目錄下產生一個test_module.o檔案,接下來串連:

# cc -shared -L/usr/local/lib -rdynamic -o test_module/test_module.so test_module/test_module.o

三. 調用第三方C/C++庫

在PHP擴充模組中調用第三方的C/C++庫,與普通的C/C++程式調用C/C++庫一樣,只要把庫檔案的位置放對就可以了。下面舉例說明:

1. 調用動態庫a.so

需要的檔案,a.so,a.h(a.h主要做資料類型聲明和入口函式宣告),都放在 test_module目錄下。

調用a.so:

1) 在test_module.c的開頭添加a.h:

#include "php.h

#include "php_ini.h"
#include "a.h"
添加了標頭檔後,可以在test_module.c的函數中調用a.so的函數介面。

2) 重新編譯連結,連結時加入a.so:

# cd phpsrc/ext
# cc -fpic -DCOMPILE_DL_TEST_MODULE=1 -I/usr/local/include -I. -I../main -I.. -I../TSRM -I../Zend -c -o test_module/test_module.o test_module/test_module.c

執行完之後會在 目錄下產生一個test_module.o檔案,接下來串連:

# cc -shared -L/usr/local/lib -rdynamic -o test_module/test_module.so test_module/test_module.o test_module/a.so

[如果a.so內部實現是C++,連結時還應該加入參數 –lstdc++,即:

# cc –shared –lstdc++ -L/usr/local/lib -rdynamic -o test_module/test_module.so test_module/test_module.o test_module/a.so

]

3) 測試test_module.so時,把test_module.so和a.so都拷貝到phpbin/lib/php/extensions/下。

2. 調用靜態庫a.a

需要的檔案,a.so,a.h(a.h主要做資料類型聲明和入口函式宣告),都放在 test_module目錄下。

調用a.a:

1) 和2)都與調用a.so相同。

3) 測試test_module.so時,把test_module.so拷貝到phpbin/lib/php/extensions/下,a.a不需要。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.