在Web開發中,URL驗證是基礎且關鍵的環節。本文系統梳理了PHP中驗證URL合法性的兩大主流方案:正則表達式格式校驗與網絡請求可達性檢測,並提供生產級代碼示例與避坑指南。
此方案僅檢查URL字符串是否符合RFC 3986規範,不發起網絡請求,速度極快,適合表單驗證、數據清洗等高頻場景。
function isValidUrl($url) {
$pattern = '/^https?:\/\/' . // 協議 https:// 或 https://
'(' .
'(([0-9]{1,3}\.){3}[0-9]{1,3})' . // IP地址格式 如 199.194.52.184
'|' . // 或
'([0-9a-z_!~\*\'\(\)\-\.]+\.)*' . // 子域名 如 www. api.
'([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\.' . // 二級域名
'[a-z]{2,6})' . // 頂級域 .com .net .museum 等
'(:[0-9]{1,4})?' . // 端口 :80
'(\/\/?|' . // 路徑開頭
'(\/[0-9a-zA-Z_!~\*\'\(\)\.\;\?\:@&=\+\$\/%#-]*)?)' . // 具體路徑/查詢參數
'$/i'; // 忽略大小寫
if (!preg_match($pattern, $url)) {
throw new InvalidArgumentException('URL格式不合法: ' . $url);
}
return true;
}
i 修飾符忽略大小寫,兼容 HTTP://EXAMPLE.COM 寫法.\*+?^${}()|[]\ 避免正則錯誤die(),便於上層統一錯誤處理通過發起真實HTTP請求,驗證URL是否真實存在且可訪問。適用於鏈接有效性掃描、死鏈檢測、第三方接口可用性監控等場景。
function checkUrlReachable($url, $timeout = 10) {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_NOBODY => true, // 只獲取頭部,不下載內容
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true, // 自動跟隨重定向
CURLOPT_MAXREDIRS => 5, // 限制重定向次數防循環
CURLOPT_TIMEOUT => $timeout, // 總超時秒數
CURLOPT_CONNECTTIMEOUT => 5, // 連接超時
CURLOPT_SSL_VERIFYPEER => false, // 生產環境建議開啟並配置CA證書
CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible; URL-Checker/1.0)',
]);
$result = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($result === false) {
return ['reachable' => false, 'error' => $error, 'code' => 0];
}
// 2xx 成功,3xx 重定向(最終可達),404 不存在,其他視業務定
$reachable = ($httpCode >= 200 && $httpCode < 400) || $httpCode === 404;
return [
'reachable' => $reachable,
'http_code' => $httpCode,
'error' => $error,
'effective_url' => curl_getinfo($ch, CURLINFO_EFFECTIVE_URL)
];
}
| 函數/方法 | 優點 | 缺點 | 推薦場景 |
|---|---|---|---|
| cURL | 功能全、支持並發、可控性強 | 需擴展、代碼較多 | 生產環境首選 |
| file_get_contents + stream_context | 無依賴、一行代碼 | 難控制超時細節、無並發 | 簡單腳本、快速驗證 |
| fopen/fread | 流式處理大文件 | 代碼複雜、易出錯 | 特殊協議需求 |
| get_headers() | 極簡單 | 無法設置超時、跟隨重定向行為不可控 | 僅獲取頭部信息 |
生產環境建議採用「格式校驗 + 異步可達性檢測」雙層架構:
example.com 需自動補全 https:// 再校驗idn_to_ascii() 轉碼後再匹配rawurlencode() 處理路徑部分URL驗證無銀彈,關鍵在於明確業務邊界:純格式校驗用正則,可用性檢測用cURL HEAD請求。結合分層架構與緩存策略,即可構建高性能、高可靠的URL驗證體系。