----------------------------------------------------
得到一份PHP源碼,我這裏用的是 php-5.3.0.tar.gz
解壓
進入到 ext 目錄下。
$./ext_skel --extname=jason_php_module //jason_php_module 爲自定義的模塊名
進入到生成的目錄 jason_php_module 目錄中,有一些文件和目錄。
config.m4 // linux下編譯配置文件
config.w32 // win32 下編譯配置文件
CREDITS
EXPERIMENTAL
jason_php_module.c
jason_php_module.php
php_jason_php_module.h
tests
可以根據提示來修改config.m4文件,這裏有幾個重要的宏命令如下:
* dnl 是註釋;
* PHP_ARG_WITH 或者 PHP_ARG_ENABLE 指定了PHP擴展模塊的工作方式,前者意味着不需要第三方庫,後者正好相反;
* PHP_REQUIRE_CXX 用於指定這個擴展用到了C++;
* PHP_ADD_INCLUDE 指定PHP擴展模塊用到的頭文件目錄;
* PHP_CHECK_LIBRARY 指定PHP擴展模塊PHP_ADD_LIBRARY_WITH_PATH定義以及庫連接錯誤信息等;
* PHP_ADD_LIBRARY(stdc++,"",EXTERN_NAME_LIBADD)用於將標準C++庫鏈接進入擴展
* PHP_SUBST(EXTERN_NAME_SHARED_LIBADD) 用於說明這個擴展編譯成動態鏈接庫的形式;
* PHP_NEW_EXTENSION 用於指定有哪些源文件應該被編譯,文件和文件之間用空格隔開;
ext_skel默認生成的模塊框架是針對C的,
如果我們要使用C++進行PHP擴展, 那除以上的PHP_REQUIRE_CXX, PHP_ADD_LIBRARY兩個宏必需外,還要把jason_php_module.c改名成jason_php_module.cpp。
需要注意的是,在config.m4裏面可以使用類似的Makefile語法,片段如下:
PHP_REQUIRE_CXX()
INCLUDES="$INCLUDES `mysql_config --cflags`"
PHP_ADD_LIBRARY(stdc++, "", EXTRA_LDFLAGS)
EXTRA_LDFLAGS="$EXTRA_LDFLAGS `mysql_config --libs` -lmemcached"
AC_CHECK_HEADERS([mysql/mysql.h])
CPPFILE="ext_name.cpp antiForbitWord.cpp antiBaseDict.cpp Trie.cpp Logger.cpp antiEncodeConverter.cpp strnormalize.cpp"
PHP_NEW_EXTENSION(ext_name, $CPPFILE, $ext_shared)
----------------------------------------------------
修改php_jason_php_module.h 文件
由於TSRM.h這個文件所包含的函數和類都是用純C語言寫的,故應該使用extern來說明如下:
extern "C" {
#ifdef ZTS
#include "TSRM.h"
#endif
}
如果該php_ext_name.h頭文件或者ext_name.cpp文件用到了C++語言中的一些容器或者一些函數,則需要在頭文件中包含相應的c++庫的頭文件,否則會出現找不到相應的C++函數錯誤。
----------------------------------------------------
修改jason_php_module.cpp這個cpp文件。
由於config.h、php.h、php_ini.h和ext/standard/info.h中包含的函數和類如TSRM.h一樣,都是用純C語言寫的,所以也需要用extern說明如下:
extern "C" {
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
}
而 #include "php_ext_name.h" 這句則已經不需要包含在extern "C"內,另外,ZEND_GET_MODULE這個宏命令也是需要特別申明如下:
#ifdef COMPILE_DL_EXT_NAME
BEGIN_EXTERN_C()
ZEND_GET_MODULE(ext_name)
END_EXTERN_C()
#endif
總之,把一些C寫的庫或轟用兼容的方式給解決
---------------------------------------------------
現在可以去編譯擴展模塊了。如果你想把它編譯成靜態模塊(把它做爲PHP的一個部分編譯進PHP中去),去到PHP的根目錄$PHP_HOME,刪去 configure 文件和運行buildconf (譯:需要libtool的支持)。
然後用你平常用的參數運行 configure 並加上--enable-php5cpp 項。運行 make clean, make, make install ,並完成其它的一些必要操作,如:重新編譯Apache。
如果你想用動態鏈接庫的方式編譯擴展模塊,到你的模塊的目錄下,運行phpize 命令(假設你已經安裝了PEAR),它會爲你的模塊創建一個 configure 腳本。然後運行configure, make 和 make install。如果你想讓你的模塊自動加載,你要修改php.ini 以加載正確的文件。如:加上類似的一行:extension=php5cpp.so 。
$phpize
$./configure
$make
注意:
在運行 Phpize命令之後 如果出現錯誤
PHP Api Version: 20041225
Zend Module Api No: 20060613
Zend Extension Api No: 220060519
Cannot find autoconf. Please check your autoconf installation and the
$PHP_AUTOCONF environment variable. Then, rerun this script.
根據網上的解決辦法是:
# fetch http://ftp.gnu.org/gnu/m4/m4-1.4.9.tar.gz
# tar -zvxf m4-1.4.9.tar.gz # cd m4-1.4.9/
# ./configure && make && make install # cd ../
# fetch http://ftp.gnu.org/gnu/autoconf/autoconf-2.62.tar.gz
# tar -zvxf autoconf-2.62.tar.gz # cd autoconf-2.62/
# ./configure && make && make install
這樣就可以了
用phpize生成configure執行文件後,可以用./configure --help查看幫助信息,修改config.m4文件可以修改configure的幫助信息。每次修改了config.m4文件,需要使用清除臨時文件命令phpize --clean來完成消除configure。
現在你的PHP擴展模塊已經編譯好了。試着運行一下在模塊目錄下自動生成的php5cpp.php ,看看是不是一切正常?:)
------------------------------------
怎麼使用寫好的擴展就不細說了
調試的時候,可以在PHP 裏用 dl('jason_php_module.so');
應用中,可以根據情況編譯進PHP中,或配置進PHP中。