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

PHP 獲取網頁 HTTP 狀態碼完整方案:fsockopen、cURL、Snoopy 對比

     編輯:PHP 綜合知識

監控網站可用性、檢測鏈接有效性、SEO 爬蟲等場景都需要獲取 HTTP 狀態碼。本文提供三種主流 PHP 實現方案,含完整代碼、性能對比、適用場景分析。

方案一:fsockopen 底層 Socket 實現(最輕量)

優點:無擴展依賴、可控性強、支援 HTTPS

缺點:代碼較多、需手動處理協議細節

function get_http_code_fsockopen($url = "localhost", $port = 80, $timeout = 10) {
    set_time_limit(0);
    ignore_user_abort(true);
    
    // 計時開始
    $start = microtime(true);
    
    // URL 標準化
    if (!preg_match("/^https?:\/\//i", $url)) {
        $url = "https://" . $url;
    }
    
    // HTTPS 端口調整
    if (preg_match("/^https:/i", $url)) {
        $port = 443;
    }
    
    // 解析 URL
    $parts = parse_url($url);
    $host = $parts['host'];
    $path = $parts['path'] ?? '/';
    $query = $parts['query'] ?? '';
    $uri = $path . ($query ? '?' . $query : '');
    
    // 建立連接
    $fp = @fsockopen($host, $port, $errno, $errstr, $timeout);
    if (!$fp) {
        return array('code' => -1, 'time' => microtime(true) - $start, 'error' => $errstr);
    }
    
    // 發送請求
    $request = "GET $uri HTTP/1.1\r\n";
    $request .= "Host: $host\r\n";
    $request .= "Connection: Close\r\n\r\n";
    
    fwrite($fp, $request);
    
    // 讀取首行狀態
    $response = fgets($fp, 1024);
    fclose($fp);
    
    // 解析狀態碼
    if (preg_match("/HTTP\/\d\.\d\s+(\d+)/i", $response, $matches)) {
        $code = (int)$matches[1];
    } else {
        $code = -2;
    }
    
    return array(
        'code' => $code,
        'time' => microtime(true) - $start,
        'raw' => $response
    );
}

方案二:cURL 實現(功能最豐富)

優點:功能完整、支援並發、處理重定向、認證、代理

缺點:依賴 cURL 擴展、相對較重

function get_http_code_curl($url, $timeout = 10) {
    $ch = curl_init();
    curl_setopt_array($ch, array(
        CURLOPT_URL            => $url,
        CURLOPT_NOBODY         => true,      // 只獲取頭部(HEAD 請求)
        CURLOPT_HEADER         => true,      // 包含頭部
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => $timeout,
        CURLOPT_FOLLOWLOCATION => true,      // 跟隨重定向
        CURLOPT_MAXREDIRS      => 5,
        CURLOPT_USERAGENT      => 'Mozilla/5.0 (PHP Status Checker)',
        CURLOPT_SSL_VERIFYPEER => false,     // 開發環境關閉驗證
    ));
    
    $start = microtime(true);
    $response = curl_exec($ch);
    $time = microtime(true) - $start;
    
    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $error = curl_error($ch);
    curl_close($ch);
    
    return array(
        'code' => $code ?: -1,
        'time' => $time,
        'error' => $error,
        'info' => curl_getinfo($ch)
    );
}

// 獲取響應體並限制大小(避免大文件)
function get_http_with_body($url, $max_bytes = 500) {
    $ch = curl_init($url);
    curl_setopt_array($ch, array(
        CURLOPT_RANGE           => "0-$max_bytes",
        CURLOPT_BINARYTRANSFER  => true,
        CURLOPT_RETURNTRANSFER  => true,
        CURLOPT_WRITEFUNCTION   => function($ch, $chunk) use ($max_bytes) {
            static $data = '';
            $len = strlen($data) + strlen($chunk);
            if ($len >= $max_bytes) {
                $data .= substr($chunk, 0, $max_bytes - strlen($data));
                return -1;  // 停止接收
            }
            $data .= $chunk;
            return strlen($chunk);
        }
    ));
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}

方案三:Snoopy 類(經典模擬瀏覽器)

適用場景:需要完整模擬瀏覽器行為、處理複雜表單、Cookie 管理

require_once 'Snoopy.class.php';
$snoopy = new Snoopy;
$snoopy->agent = 'Mozilla/5.0 (compatible; PHP Status Checker)';
$snoopy->read_timeout = 10;

if ($snoopy->fetch($url)) {
    $code = $snoopy->status;  // 如 "HTTP/1.1 200 OK"
    preg_match('/\d{3}/', $code, $m);
    return array('code' => (int)$m[0], 'headers' => $snoopy->headers);
}
return array('code' => -1, 'error' => 'Fetch failed');

常見 HTTP 狀態碼速查

代碼含義典型場景
200OK正常返回
301Moved Permanently永久重定向(SEO 傳遞權重)
302Found臨時重定向
403Forbidden權限不足
404Not Found頁面不存在
500Internal Server Error服務器錯誤
503Service Unavailable服務不可用/維護中

方案選型建議

場景推薦方案理由
簡單監控/批量檢測cURL (HEAD)速度快、資源佔用少
需處理重定向鏈cURL自動跟隨、獲取最終 URL
無 cURL 擴展環境fsockopen原生支援、零依賴
複雜表單/登錄態檢測Snoopy/GuzzleCookie/Session 管理完善
高併發異步檢測cURL Multi / Swoole並發控制、非阻塞

生產環境最佳實踐

  1. 超時控制:連接 5s、讀取 10s,避免阻塞
  2. 錯誤重試:網絡抖動時指數退避重試 2-3 次
  3. 結果緩存:同一 URL 短時間內複用結果
  4. User-Agent:設置標識避免被防火牆攔截
  5. SSL 驗證:生產環境啟用 CURLOPT_SSL_VERIFYPEER

更多網絡編程技巧:《PHP網絡編程實戰》、《高性能爬蟲開發指南》

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved