首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 編寫 C 擴展完整教程:從骨架到參數處理

     編輯:PHP 相關知識

為 PHP 編寫 C 語言擴展能突破性能瓶頸、封裝底層庫。本文以 ext_skel 生成骨架為起點,詳細記錄 config.m4 配置、C/頭文件修改、編譯安裝、php.ini 掛載、函數參數解析(zend_parse_parameters)全流程,並提供帶參數函數實例。

環境準備

  • PHP 源碼包(與目標版本一致),已 ./configure && make 過(生成 phpize、頭文件)。
  • GCC、autoconf、automake、libtool。

步驟 1:生成擴展骨架

cd php-src/ext
./ext_skel --extname=hmc
# 生成 hmc/ 目錄,包含 config.m4, hmc.c, php_hmc.h, tests/ 等

步驟 2:修改 config.m4 啟用擴展

# 編輯 hmc/config.m4
# 找到並取消註釋以下其中一組(推薦 PHP_ARG_ENABLE,編譯時用 --enable-hmc)

PHP_ARG_ENABLE(hmc, whether to enable hmc support,
[  --enable-hmc           Enable hmc support])

# 原註釋行以 dnl 開頭,刪除 dnl 即可

步驟 3:實現 C 邏輯 (hmc.c)

#include "php_hmc.h"

// 1. 宣告函數入口表
const zend_function_entry hmc_functions[] = {
    PHP_FE(confirm_hmc_compiled, NULL)   // 測試用,保留或移除
    PHP_FE(say_hello, NULL)              // 新增:我們的函數
    PHP_FE_END                           // 必須以此結尾
};

// 2. 模組入口結構體(通常無需修改)
zend_module_entry hmc_module_entry = {
    STANDARD_MODULE_HEADER,
    "hmc",
    hmc_functions,
    NULL, NULL, NULL, NULL, NULL,
    "0.1.0",
    STANDARD_MODULE_PROPERTIES
};

ZEND_GET_MODULE(hmc)

// 3. 實現 say_hello() 無參版
PHP_FUNCTION(say_hello) {
    php_printf("hello world\n");
}

// 4. 實現帶參數版本(替換上方)
PHP_FUNCTION(say_hello) {
    char *name;
    size_t name_len;

    // 解析參數:1 個字串,"s" 類型
    if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) {
        return; // 錯誤已由引擎拋出
    }

    php_printf("hello world, %s\n", name);
}

步驟 4:更新頭文件 (php_hmc.h)

#ifndef PHP_HMC_H
#define PHP_HMC_H

extern zend_module_entry hmc_module_entry;
#define phpext_hmc_ptr &hmc_module_entry

#define PHP_HMC_VERSION "0.1.0"

PHP_FUNCTION(confirm_hmc_compiled);
PHP_FUNCTION(say_hello); // 新增宣告

#endif

步驟 5:編譯安裝

cd hmc
phpize                    # 生成 configure、Makefile 等
./configure --enable-hmc  # 指定啟用本擴展
make
sudo make install
# 輸出:Installing shared extensions: /usr/lib/php/20210902/hmc.so

步驟 6:掛載擴展並驗證

# 1. 找到 php.ini
php --ini

# 2. 在 [PHP] 區塊添加
extension=hmc.so

# 3. 重啟 PHP-FPM / Apache
sudo systemctl restart php8.1-fpm

# 4. 驗證
php -m | grep hmc          # 列表中出現 hmc
php -r "say_hello();"      # 輸出: hello world
php -r "say_hello('PHP');" # 輸出: hello world, PHP

進階:zend_parse_parameters 類型規範速查

字元C 類型PHP 類型備註
lzend_longint平台相關長度 (32/64位)
ddoublefloat
schar*, size_tstring二進制安全,需配合長度變量
bzend_boolbool0/1
azval*array返回 HashTable*
ozval*object
rzval*resource
zzval*mixed任意類型,不分離
|後續參數為可選
/強制分離 zval (copy-on-write)
!允許 null (僅用於 a, o, O, r, z)

常見問題排查

  • phpize: command not found → 安裝 php-dev / php-devel 包。
  • configure: error: Cannot find php.h → 確保 PHP 源碼已 make 或安裝開發包。
  • 函數未導出 → 檢查 hmc_functions 表是否以 PHP_FE_END 結尾、頭文件是否宣告、PHP_FUNCTION 宏展開正確。
  • Segmentation fault → 檢查 zend_parse_parameters 格式字串與參數指標匹配、記憶體管理 (emalloc/efree) 配對。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved