php 通用的調用 so的方法是使用dl()函數,但是在php5.3之後不再支援這種方法,僅支援靜態調用,使用dl() 動態調用的方法見:
引用頁1: http://tech.idv2.com/2007/07/06/use-local-so-in-php/
感謝原作者提供的清晰明了的方法,但是我在5.3.1版本i中沒有通過,於是我找到了頁面:
引用頁2: http://www.9php.com/FAQ/cxsjl/php/2007/11/9405479103083.html
此頁面中有討論到如何靜態調用so檔案中的函數的描述,解決方案如下:
環境:Apache 2.2.9
php5.3.2
首先使用引用頁1提供的方法產生動態庫 libhello.so.
進入php 安裝包解壓縮目錄
-laptop:~/dev/software/php-5.3.2$cd ext
funny@funny-laptop:~/dev/software/php-5.3.2/ext$
建立中間 php連結so項目cltest
funny@funny-laptop:~/dev/software/php-5.3.2/ext$ ./ext_skel --extname=cltest
Creating directory cltest
Creating basic files: config.m4 config.w32 .cvsignore cltest.c php_cltest.h CREDITS EXPERIMENTAL tests/001.phpt cltest.php [done].
To use your new extension, you will have to execute the following steps:
1. $ cd ..
2. $ vi ext/cltest/config.m4
3. $ ./buildconf
4. $ ./configure --[with|enable]-cltest
5. $ make
6. $ ./php -f ext/cltest/cltest.php
7. $ vi ext/cltest/cltest.c
8. $ make
Repeat steps 3-6 until you are satisfied with ext/cltest/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.
修改 設定檔config.m4
funny@funny-laptop:~/dev/software/php-5.3.2/ext$ vi cltest/config.m4
刪除 3 個 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])
或者刪除 下邊這3個 dnl
dnl PHP_ARG_ENABLE(my_module, whether to enable my_module support,
dnl Make sure that the comment is aligned:
dnl [ --enable-my_module Enable my_module support])
修改完畢。
在cltest.c擴充模組的主程式檔案中加PHP的函數定義
主程式中描述了php擴充模組的聲明,模組中含有多少個函數,各個函數的作用,在phpinfo函數中顯示什麼內容,模組初始化做些什麼,結束做些什麼都會在這個檔案裡進行描述。我們在上面只是添加了一個函數say_hello,並且描述了say_hello函數的具體內容
[root@test1 ext]# Vi cltest.c
function_entry my_module_functions[] = {
PHP_FE(say_hello, NULL) /* ?添加這一行代碼 註冊函數say_hello() */
PHP_FE(hello_add, NULL) /* ?添加這一行代碼 註冊函數hello_add() */
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)
{
RETURN_STRINGL("hello world",11,1);
}
PHP_FUNCTION(hello_add)
{
long int a, b;
long int result;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &a, &b) == FAILURE) {
return;
}
result = hello_add(a, b);
RETURN_LONG(result);
}
修改完畢。
在cltest.h擴充模組的標頭檔中加PHP啟動時要註冊的函數
在對應的標頭檔中聲明了say_hello這個函數,從而完成了我們預期的功能。
funny@funny-laptop:~/dev/software/php-5.3.2/ext$ gedit cltest/php_cltest.h
在檔案中PHP_FUNCTION(confirm_my_module_compiled);一行前面添加下面的代碼 函數定義
PHP_FUNCTION(say_hello);
PHP_FUNCTION(hello_add);
儲存檔案並退出
然後執行 phpize 程式,產生configure指令碼:
$ phpize
funny@funny-laptop:~/dev/software/php-5.3.2/ext$ cd cltest
funny@funny-laptop:~/dev/software/php-5.3.2/ext/cltest$ phpize
Configuring for:
PHP Api Version: 20090626
Zend Module Api No: 20090626
Zend Extension Api No: 220090626
準備工作完成可以進行編譯
$ ./configure
因為要調用引用頁 1中產生的libhello.so 動態庫,所以使用如下方法邊緣
$ make LDFLAGS=-lhello
編譯完成後會在 modules 下產生 cltest.so檔案此檔案符合php的調用要求,我們只需要把該檔案放在php要載入的模組的目錄下,並把該模組名稱寫入php.ini,重啟伺服器即可
具體操作如下
php.ini 中添加路徑
extension_dir=/opt/php/lib/php/extensions
extension=gettext.so
儲存並重啟 apache
測試
<?php
echo hello_add(3, 4);
?>
輸出 7
或者
<?php
echo say_hello();
?>
輸出 hello world
函數調用成功