開發 PHP 擴充(Extension)能以 C 語言效能解決效能瓶頸、封裝 C/C++ 函式庫、實現底層系統呼叫。PHP 官方提供 ext_skel 腳本,可一鍵生成標準目錄結構與樣板程式碼。本文詳細說明 Linux/Windows 環境下的生成步驟、關鍵檔案用途、編譯安裝流程,並補充常見問題與開發建議。
# 1. 進入 PHP 原始碼 ext 目錄 cd /path/to/php-src/ext # 2. 執行 ext_skel 生成骨架(以 simple 為例) ./ext_skel --extname=simple # 輸出: # Creating directory simple # Creating basic files: config.m4 config.w32 .svnignore simple.c php_simple.h CREDITS EXPERIMENTAL tests/001.phpt simple.php [done]. # 3. 依提示操作 cd .. vi ext/simple/config.m4 # 啟用擴充編譯選項 ./buildconf # 重新生成 configure ./configure --enable-simple # 加入 --enable-simple 參數 make # 編譯 ./sapi/cli/php -f ext/simple/simple.php # 測試 vi ext/simple/simple.c # 開始撰寫實際邏輯 make # 重新編譯 # 重複 3-6 步驟直到滿意
# 1. 進入 PHP 原始碼 ext 目錄 cd C:\php-src\ext # 2. 執行 Windows 版骨架生成腳本 php.exe ext_skel_win32.php --extname=simple # 後續步驟類似 Linux,但編譯環境需 Visual Studio + PHP SDK # 參考官方文檔:https://wiki.php.net/internals/windows/stepbystepbuild
| 檔案 | 用途 |
|---|---|
config.m4 | Linux/Mac 編譯配置:定義 PHP_ARG_ENABLE、依賴函式庫、編譯旗標 |
config.w32 | Windows 編譯配置:對應 config.m4 的 JS 版本 |
php_simple.h | 標頭檔:宣告擴充進入點、版本、函式原型、結構體 |
simple.c | 核心實作:PHP_MINIT_FUNCTION、PHP_RINIT_FUNCTION、函式實作、zend_function_entry 表 |
tests/001.phpt | PHPT 測試腳本:供 make test 執行,驗證功能正確性 |
simple.php | PHP 測試腳本:載入擴充並呼叫導出函式 |
# 預設被註解,需取消註解並調整 PHP_ARG_ENABLE(simple, whether to enable simple support, [ --enable-simple Enable simple support]) if test "$PHP_SIMPLE" != "no"; then # 若需連結外部函式庫(如 libcurl),在此添加 # PHP_ADD_LIBRARY_WITH_PATH(curl, /usr/local/lib, SIMPLE_SHARED_LIBADD) # PHP_ADD_INCLUDE(/usr/local/include) PHP_NEW_EXTENSION(simple, simple.c, $ext_shared) fi
// 1. 標準模組進入點
zend_module_entry simple_module_entry = {
STANDARD_MODULE_HEADER,
"simple", // 擴充名稱
simple_functions, // 函式表
PHP_MINIT(simple), // 模組啟動
PHP_MSHUTDOWN(simple), // 模組關閉
PHP_RINIT(simple), // 請求啟動
PHP_RSHUTDOWN(simple), // 請求關閉
PHP_MINFO(simple), // phpinfo() 顯示
PHP_SIMPLE_VERSION, // 版本
STANDARD_MODULE_PROPERTIES
};
// 2. 函式表:導出至 PHP 的函式
const zend_function_entry simple_functions[] = {
PHP_FE(confirm_simple_compiled, NULL) // 範例函式
PHP_FE_END
};
// 3. 模組啟動:註冊常數、類別、資源型別
PHP_MINIT_FUNCTION(simple) {
REGISTER_LONG_CONSTANT("SIMPLE_VERSION", 1, CONST_CS | CONST_PERSISTENT);
return SUCCESS;
}
// 4. 實作導出函式
PHP_FUNCTION(confirm_simple_compiled) {
char *arg = NULL;
size_t arg_len;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &arg, &arg_len) == FAILURE) {
return;
}
php_printf("Congratulations! You have successfully compiled ext/simple\n");
php_printf("Argument: %s\n", arg);
RETURN_TRUE;
}
ext/ 目錄執行,或使用完整路徑。config.m4 語法、確認已安裝 autoconf、libtool、pkg-config。config.m4 未正確連結外部函式庫,補全 PHP_ADD_LIBRARY_WITH_PATH。tests/001.phpt 符合實際函式簽名,執行 make test 驗證。ext/standard/、ext/json/、ext/pdo/ 為最佳範例gdb + .gdbinit(PHP 原始碼提供)、valgrind 檢測記憶體洩漏ext_skel 是 PHP 擴充開發的起點,掌握其生成流程、關鍵檔案結構與編譯步驟,即可進入 PHP 核心開發領域。建議從簡單函式導出開始,逐步挑戰類別封裝、資源管理、生命週期鉤子,並善用 PHPT 撰寫測試,確保擴充品質與相容性。