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

PHP 擴展生命週期四大鉤子:MINIT/MSHUTDOWN/RINIT/RSHUTDOWN 詳細實作

     編輯:PHP 綜合知識

PHP 擴展透過四對生命週期鉤子參與 SAPI 啟動/關閉與請求處理流程。本文建立 sample4 完整骨架,詳細解析各階段時機、用途、回傳值意義與實作模式。

四階段時機總覽

鉤子觸發時機執行頻率典型用途
MINITSAPI 啟動後、首個請求前每進程一次註冊常數、類別、資源型別、INI 設定、流包裝器
MSHUTDOWNSAPI 關閉前每進程一次釋放持久資源、關閉連線池、清理全域狀態
RINIT每個請求開始每請求一次初始化請求級變數、建立 DB 連線、啟動 Session
RSHUTDOWN每個請求結束每請求一次釋放請求級資源、提交/回滾事務、寫入 Session

sample4 完整骨架程式碼

php-src/ext/sample4/
├── config.m4
├── php_sample4.h
└── sample4.c

config.m4

PHP_ARG_ENABLE(sample4, [Whether to enable the "sample4" extension],
    [  --enable-sample4    Enable "sample4" extension support])

if test "$PHP_SAMPLE4" != "no"; then
    PHP_SUBST(SAMPLE4_SHARED_LIBADD)
    PHP_NEW_EXTENSION(sample4, sample4.c, $ext_shared)
fi

php_sample4.h

#ifndef PHP_SAMPLE4_H
#define PHP_SAMPLE4_H

#define PHP_SAMPLE4_EXTNAME "sample4"
#define PHP_SAMPLE4_EXTVER  "1.0"

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"

extern zend_module_entry sample4_module_entry;
#define phpext_sample4_ptr &sample4_module_entry

#endif

sample4.c

#include "php_sample4.h"
#include "ext/standard/info.h"  // php_info_print_table_* 需要

static function_entry php_sample4_functions[] = {
    {NULL, NULL, NULL}
};

// MINIT: 模組初始化
PHP_MINIT_FUNCTION(sample4) {
    // 註冊常數
    REGISTER_LONG_CONSTANT("SAMPLE4_VERSION", 1, CONST_CS | CONST_PERSISTENT);
    
    // 註冊資源型別
    // le_sample4_res = zend_register_list_destructors_ex(...);
    
    // 註冊 INI 設定 (見下一章)
    // REGISTER_INI_ENTRIES();
    
    return SUCCESS;
}

// MSHUTDOWN: 模組關閉
PHP_MSHUTDOWN_FUNCTION(sample4) {
    // 取消註冊 INI 設定
    // UNREGISTER_INI_ENTRIES();
    
    // 釋放持久資源
    // zend_hash_destroy(&persistent_resources);
    
    return SUCCESS;
}

// RINIT: 請求初始化
PHP_RINIT_FUNCTION(sample4) {
    // 初始化請求級全域變數
    // SG(my_global) = 0;
    
    // 建立資料庫連線 (非持久)
    // SG(db_link) = mysql_connect(...);
    
    return SUCCESS;
}

// RSHUTDOWN: 請求關閉
PHP_RSHUTDOWN_FUNCTION(sample4) {
    // 關閉非持久連線
    // if (SG(db_link)) mysql_close(SG(db_link));
    
    // 清理請求級資源
    return SUCCESS;
}

// MINFO: phpinfo() 顯示資訊
PHP_MINFO_FUNCTION(sample4) {
    php_info_print_table_start();
    php_info_print_table_header(2, "sample4 support", "enabled");
    php_info_print_table_row(2, "Version", PHP_SAMPLE4_EXTVER);
    php_info_print_table_row(2, "Author", "Your Name");
    php_info_print_table_end();
    
    // 顯示 INI 設定
    DISPLAY_INI_ENTRIES();
}

zend_module_entry sample4_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
    STANDARD_MODULE_HEADER,
#endif
    PHP_SAMPLE4_EXTNAME,
    php_sample4_functions,
    PHP_MINIT(sample4),
    PHP_MSHUTDOWN(sample4),
    PHP_RINIT(sample4),
    PHP_RSHUTDOWN(sample4),
    PHP_MINFO(sample4),
#if ZEND_MODULE_API_NO >= 20010901
    PHP_SAMPLE4_EXTVER,
#endif
    STANDARD_MODULE_PROPERTIES
};

#ifdef COMPILE_DL_SAMPLE4
ZEND_GET_MODULE(sample4)
#endif

關鍵規則:回傳值決定成敗

  • 所有鉤子**必須回傳 SUCCESS (0)** 表示成功。
  • 回傳 FAILURE (-1) 將導致:
階段回傳 FAILURE後果
MINIT模組載入失敗,PHP 啟動中止 (CLI) 或 SAPI 拒絕載入
RINIT請求處理中止,直接進入 RSHUTDOWN,回傳 500/白頁
MSHUTDOWN/RSHUTDOWN記錄錯誤日誌,但不中斷流程

線程安全環境 (ZTS) 額外鉤子

  • GINIT / GSHUTDOWN:每線程啟動/關閉 (僅 ZTS)。
  • 用於線程局部儲存 (TLS) 初始化與清理。
  • 在 zend_module_entry 中對應 globals_ctor / globals_dtor。

實作最佳實踐

  1. MINIT:只做「一次性、跨請求持久」的初始化。避免耗時操作阻塞啟動。
  2. RINIT:輕量級請求初始化。資料庫連線建議用持久連線 (MINIT 建立) 或連線池。
  3. RSHUTDOWN:確保釋放**所有**請求級資源,防止洩漏累積。
  4. MSHUTDOWN:對稱釋放 MINIT 分配的持久資源。
  5. MINFO:提供有用的除錯資訊 (版本、作者、INI 設定、統計計數器)。

常見錯誤模式

// 錯誤:在 MINIT 中建立非持久資源
PHP_MINIT_FUNCTION(bad) {
    SG(db) = mysql_connect(...); // 錯誤!MINIT 無請求上下文
    return SUCCESS;
}

// 正確:持久連線在 MINIT,非持久在 RINIT
PHP_MINIT_FUNCTION(good) {
    SG(persistent_db) = mysql_pconnect(...); // 持久連線
    return SUCCESS;
}

PHP_RINIT_FUNCTION(good) {
    SG(request_db) = mysql_connect(...); // 非持久,請求級
    return SUCCESS;
}

PHP_RSHUTDOWN_FUNCTION(good) {
    if (SG(request_db)) mysql_close(SG(request_db));
    return SUCCESS;
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved