PHP 擴展開發入門實戰:建立最小骨架(config.m4、php_sample.h、sample.c),理解 zend_module_entry 結構,編譯安裝並驗證載入。
php-src/ext/sample/
├── config.m4 # 建構配置
├── php_sample.h # 頭文件:常數、入口宣告
└── sample.c # 核心實作
PHP_ARG_ENABLE(sample, [Whether to enable the "sample" extension],
[ --enable-sample Enable "sample" extension support])
if test "$PHP_SAMPLE" != "no"; then
PHP_SUBST(SAMPLE_SHARED_LIBADD)
PHP_NEW_EXTENSION(sample, sample.c, $ext_shared)
fi
PHP_ARG_ENABLE:產生 --enable-sample 選項,無外部依賴用 enable;有依賴用 PHP_ARG_WITH (產生 --with-sample)。PHP_NEW_EXTENSION:宣告擴展名稱、源檔列表、共享模組標記。#ifndef PHP_SAMPLE_H
#define PHP_SAMPLE_H
#define PHP_SAMPLE_EXTNAME "sample"
#define PHP_SAMPLE_EXTVER "1.0"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h" // 核心 API 總入口
extern zend_module_entry sample_module_entry;
#define phpext_sample_ptr &sample_module_entry
#endif
HAVE_CONFIG_H:phpize 建構時由 config.h 定義。php.h 包含核心所有公共 API 頭文件。zend_module_entry 宣告為 extern,供 dlopen()/dlsym() 尋找入口。#include "php_sample.h"
zend_module_entry sample_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
PHP_SAMPLE_EXTNAME,
NULL, // Functions (function_entry 陣列)
NULL, // MINIT
NULL, // MSHUTDOWN
NULL, // RINIT
NULL, // RSHUTDOWN
NULL, // MINFO
#if ZEND_MODULE_API_NO >= 20010901
PHP_SAMPLE_EXTVER,
#endif
STANDARD_MODULE_PROPERTIES
};
#ifdef COMPILE_DL_SAMPLE
ZEND_GET_MODULE(sample) // 共享模組導出符號
#endif
cd php-src/ext/samplephpize(生成 configure、Makefile 等建構檔)。./configure --enable-sample --enable-debug --enable-maintainer-ztsmakemake install(輸出 .so 至擴展目錄)。php.ini 加入 extension=sample.so。php -m | grep sample 驗證。| 宏 | 用途 |
|---|---|
STANDARD_MODULE_HEADER | 填充 size、zend_api、zend_debug、zts 等標準欄位 |
STANDARD_MODULE_PROPERTIES | 填充 version、globals_size、globals_id 等屬性 |
ZEND_GET_MODULE | 共享模組必須導出 get_module() 函式,供 dl() 載入 |
COMPILE_DL_SAMPLE | 共享模組編譯時由建構系統定義 |