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

PHP 實現帶超時功能的 get_headers 函數替代方案

     編輯:PHP 綜合知識

PHP 內建的 get_headers() 函數雖然方便,但缺乏超時控制參數,在網路環境不佳時常導致程式卡住超過 20 秒。本文分享一個基於 cURL 實現的替代方案,支援自訂超時時間,並能解析 HTTP 標頭為結構化陣列。

問題背景

在處理 Gravatar 頭像載入優化時,發現 get_headers() 呼叫極其緩慢,甚至綁定 IP 後仍需 20 秒以上。查閱 PHP 官方文件,該函數簽名為 array get_headers(string $url[, int $format = 0]),完全沒有超時參數。深入原始碼發現其底層依賴 php_stream,且涉及 zend_parse_parameters 等內部函數,無法直接在使用者層擴展。

解決方案:cURL 實作

採用 cURL 的 CURLOPT_HEADER 和 CURLOPT_NOBODY 選項僅抓取標頭,搭配 CURLOPT_TIMEOUT 實現超時控制。核心程式碼如下:

function get_url_headers($url, $timeout = 10) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_NOBODY, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);

    $data = curl_exec($ch);
    $data = preg_split('/\n/', $data);

    $data = array_filter(array_map(function($line) {
        $line = trim($line);
        if ($line) {
            $parts = preg_split('/:\s/', $line, 2);
            switch (count($parts)) {
                case 2: return [$parts[0] => $parts[1]];
                case 1: return $parts;
                default: return null;
            }
        }
    }, $data));

    sort($data);
    foreach ($data as $key => $value) {
        $itemKey = array_keys($value)[0];
        if (is_int($itemKey)) {
            $data[$key] = $value[$itemKey];
        } elseif (is_string($itemKey)) {
            $data[$itemKey] = $value[$itemKey];
            unset($data[$key]);
        }
    }
    return $data;
}

效能比較

原版 get_headers() 回傳結果包含重複標頭(如多組 Date、Server),且耗時不可控。cURL 版本瞬間回傳,結構更乾淨,僅保留首組標頭值,適合高併發場景。實測在 Gravatar 請求中,cURL 版本穩定在 200ms 內完成,而原版頻繁超時。

注意事項

  • 需確保 PHP 安裝 cURL 擴展
  • 此實作未處理 3xx 重導向的多組標頭合併,若需完整支援可自行擴展
  • HTTPS 請求需額外設定 CURLOPT_SSL_VERIFYPEER
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved