監控網站可用性、檢測鏈接有效性、SEO 爬蟲等場景都需要獲取 HTTP 狀態碼。本文提供三種主流 PHP 實現方案,含完整代碼、性能對比、適用場景分析。
優點:無擴展依賴、可控性強、支援 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 擴展、相對較重
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;
}
適用場景:需要完整模擬瀏覽器行為、處理複雜表單、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');
| 代碼 | 含義 | 典型場景 |
|---|---|---|
| 200 | OK | 正常返回 |
| 301 | Moved Permanently | 永久重定向(SEO 傳遞權重) |
| 302 | Found | 臨時重定向 |
| 403 | Forbidden | 權限不足 |
| 404 | Not Found | 頁面不存在 |
| 500 | Internal Server Error | 服務器錯誤 |
| 503 | Service Unavailable | 服務不可用/維護中 |
| 場景 | 推薦方案 | 理由 |
|---|---|---|
| 簡單監控/批量檢測 | cURL (HEAD) | 速度快、資源佔用少 |
| 需處理重定向鏈 | cURL | 自動跟隨、獲取最終 URL |
| 無 cURL 擴展環境 | fsockopen | 原生支援、零依賴 |
| 複雜表單/登錄態檢測 | Snoopy/Guzzle | Cookie/Session 管理完善 |
| 高併發異步檢測 | cURL Multi / Swoole | 並發控制、非阻塞 |
CURLOPT_SSL_VERIFYPEER更多網絡編程技巧:《PHP網絡編程實戰》、《高性能爬蟲開發指南》