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

PHP 函數執行超時處理:register_shutdown_function 實現超時捕獲

     編輯:PHP 綜合知識

核心機制

register_shutdown_function() 註冊的函數會在以下情況執行:

  • 腳本正常執行結束
  • 呼叫 exit() 或 die()
  • 發生致命錯誤 (Fatal Error) —— 包含執行超時

可重複註冊,依序執行。

超時捕獲實作

<?php
error_reporting(0); // 生產環境建議關閉錯誤顯示,改用日誌

register_shutdown_function('handleShutdown');

function handleShutdown() {
    $error = error_get_last();
    // 判斷是否為超時錯誤
    if ($error && strpos($error['message'], 'Maximum exec') !== false) {
        echo 'handle time out';
        // 可在此處:記錄日誌、發送告警、清理資源、寫入審計追蹤
    }
}

set_time_limit(2); // 設定 2 秒超時
sleep(3);          // 故意超時

關鍵點解析

  1. error_get_last():取得最後發生的錯誤資訊 (型別、訊息、檔案、行號)
  2. strpos($error['message'], 'Maximum exec'):超時錯誤訊息特徵字串
  3. set_time_limit(2):覆蓋 php.ini 的 max_execution_time
  4. 限制:僅能捕獲 PHP 內核強制終止的超時,無法捕獲外部程式 (如資料庫查詢、cURL) 阻塞導致的超時

進階應用:超時上下文資訊記錄

function handleShutdown() {
    $error = error_get_last();
    if ($error && in_array($error['type'], [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR])) {
        $log = [
            'timestamp'   => date('c'),
            'error_type'  => $error['type'],
            'message'     => $error['message'],
            'file'        => $error['file'],
            'line'        => $error['line'],
            'memory_peak' => memory_get_peak_usage(true),
            'memory_curr' => memory_get_usage(true),
            'request_uri' => $_SERVER['REQUEST_URI'] ?? 'CLI',
            'request_method' => $_SERVER['REQUEST_METHOD'] ?? 'CLI',
        ];
        error_log(json_encode($log) . "\n", 3, __DIR__ . '/logs/fatal_errors.log');
    }
}

替代方案比較

方案原理優點缺點
register_shutdown_functionPHP 內核請求結束階段回調無需擴充、捕獲致命錯誤無法捕獲外部阻塞、無法恢復執行
pcntl_alarm + signalPOSIX 信號可中斷阻塞系統調用僅 CLI、需 pcntl 擴充、非 Windows
Swoole/Workerman 定時器事件循環管理全非阻塞、精確控制需常駐進程、架構變更大
Nginx proxy_read_timeoutWeb Server 層面保護上游服務非 PHP 內部、回傳 504 而非業務邏輯

最佳實踐建議

  1. 在 auto_prepend_file 或框架啟動階段統一註冊
  2. 區分 業務超時 (自定義邏輯) 與 執行超時 (PHP 內核)
  3. 3. 超時處理中避免耗時操作 (資料庫寫入、外部 API),防止二次超時 4. 記錄完整上下文資訊便於事後分析 5. 考慮使用 Guzzle 等支援超時的 HTTP Client 替代原生 file_get_contents/cURL

相關專題

  • 《PHP 基本語法入門教程》
  • 《PHP 錯誤與異常處理方法總結》
  • 《PHP 常用函數與技巧總結》
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved