第十四章-PHP與HTTP協議
一,HTTP 協議詳解
HTTP(HyperText Transfer Protocol,超文本傳輸協議)是互聯網上應用最廣泛的協議之一,用于客戶端(如瀏覽器)與服務器之間的通信。它是 Web 技術的基石,理解 HTTP 協議是開發 Web 應用的核心基礎。以下是 HTTP 協議的全面解析:
一、HTTP 協議基礎
1. 協議特性
- 無狀態 (Stateless)
每個 HTTP 請求相互獨立,服務器默認不保存客戶端狀態(如用戶登錄信息)。狀態管理需通過 Cookie、Session 或 Token 實現。 - 基于請求-響應模型
- 客戶端發送請求(Request) → 服務器返回響應(Response)。
- 支持多種數據格式:HTML、JSON、XML、圖片、視頻等。
- 靈活可擴展
- 通過 HTTP 頭部(Headers) 擴展功能(如緩存控制、內容協商)。
- 支持 HTTPS(HTTP + SSL/TLS)加密傳輸。
2. 協議版本
版本 | 年份 | 核心改進 |
---|---|---|
HTTP/0.9 | 1991 | 僅支持 GET 方法,返回純文本 |
HTTP/1.0 | 1996 | 支持 MIME 類型、狀態碼、Header |
HTTP/1.1 | 1999 | 持久連接、管道化、Host 頭 |
HTTP/2 | 2015 | 二進制協議、多路復用、頭部壓縮 |
HTTP/3 | 2022 | 基于 QUIC 協議(UDP)、減少延遲 |
二、HTTP 消息結構
1. 請求(Request)
GET /index.html HTTP/1.1 # 請求行:方法 + 路徑 + 協議版本
Host: www.example.com # 頭部字段(Headers)
User-Agent: Mozilla/5.0
Accept: text/html# 空行(分隔頭部和消息體)# 消息體(Body,GET 請求通常為空)
-
請求方法 (Methods)
方法 用途 冪等性 GET
獲取資源(參數在 URL) 是 POST
提交數據(參數在 Body) 否 PUT
更新完整資源 是 DELETE
刪除資源 是 PATCH
更新部分資源 否 HEAD
獲取響應頭(無 Body) 是 OPTIONS
查詢服務器支持的通信選項 是
2. 響應(Response)
HTTP/1.1 200 OK # 狀態行:協議版本 + 狀態碼 + 狀態描述
Content-Type: text/html # 頭部字段(Headers)
Content-Length: 1234
Date: Mon, 01 Jan 2024 12:00:00 GMT# 空行
<!DOCTYPE html> # 消息體(Body)
<html>...</html>
-
狀態碼 (Status Codes)
狀態碼 類別 常見示例 1xx 信息響應 100(繼續) 2xx 成功 200(OK)、201(Created) 3xx 重定向 301(永久重定向)、304(未修改) 4xx 客戶端錯誤 400(錯誤請求)、403(禁止訪問) 5xx 服務端錯誤 500(內部錯誤)、503(服務不可用)
三、核心機制詳解
1. 連接管理
- 短連接 (HTTP/1.0)
每次請求后關閉 TCP 連接,效率低。 - 持久連接 (HTTP/1.1)
- 默認保持 TCP 連接復用(
Connection: keep-alive
)。 - 通過
Content-Length
或Transfer-Encoding: chunked
處理動態內容。
- 默認保持 TCP 連接復用(
- 多路復用 (HTTP/2)
單個 TCP 連接上并行傳輸多個請求/響應,解決隊頭阻塞問題。
2. 緩存機制
- 強緩存
Cache-Control: max-age=3600
:資源有效期 1 小時。Expires: Mon, 01 Jan 2024 12:00:00 GMT
(HTTP/1.0,已被取代)。
- 協商緩存
Last-Modified
+If-Modified-Since
:基于時間戳。ETag
+If-None-Match
:基于內容哈希值。
3. 內容協商
客戶端通過 Header 聲明偏好,服務器返回最合適的內容:
Accept: text/html, application/json
(內容類型)Accept-Language: en-US, zh-CN
(語言)Accept-Encoding: gzip, deflate
(壓縮方式)
4. 安全機制
-
HTTPS
- HTTP over SSL/TLS,加密傳輸數據。
- 通過數字證書驗證服務器身份。
-
CORS (跨域資源共享)
Access-Control-Allow-Origin: https://trusted-site.com Access-Control-Allow-Methods: GET, POST
四、HTTP 頭部關鍵字段
常用請求頭
字段 | 用途 |
---|---|
Host | 目標域名(HTTP/1.1 必需) |
User-Agent | 客戶端標識(瀏覽器、操作系統) |
Cookie | 發送服務器設置的 Cookie |
Authorization | 認證憑證(如 Bearer <token> ) |
Content-Type | 請求體的 MIME 類型(如 application/json ) |
常用響應頭
字段 | 用途 |
---|---|
Set-Cookie | 設置客戶端的 Cookie |
Location | 重定向目標 URL(配合 3xx 狀態碼) |
Content-Encoding | 內容壓縮方式(如 gzip ) |
Cache-Control | 緩存策略(如 no-cache ) |
Content-Security-Policy | 防止 XSS 攻擊 |
二,常見的HTTP 響應設置
一、基礎響應設置
1. 設置 HTTP 狀態碼
// 直接設置狀態碼 (PHP >= 5.4)
http_response_code(404); // 返回 404 Not Found// 傳統方式(兼容舊版本)
header("HTTP/1.1 403 Forbidden");
2. 設置響應內容類型
// 返回 HTML
header('Content-Type: text/html; charset=utf-8');// 返回 JSON(API 開發必備)
header('Content-Type: application/json; charset=utf-8');// 返回純文本
header('Content-Type: text/plain');// 返回 XML
header('Content-Type: application/xml');
二、重定向與頁面跳轉
1. 基礎重定向
// 302 臨時重定向(默認)
header('Location: /new-page.php');
exit; // 必須立即終止腳本執行// 301 永久重定向
header('Location: /permanent-page.php', true, 301);
exit;
2. 延遲重定向
// 3 秒后跳轉
header('Refresh: 3; url=/target-page.php');
echo '即將跳轉,請稍候...';
三、緩存控制
1. 禁止瀏覽器緩存
header('Cache-Control: no-cache, no-store, must-revalidate'); // HTTP/1.1
header('Pragma: no-cache'); // HTTP/1.0
header('Expires: 0'); // 代理服務器緩存
2. 設置資源緩存時間
// 緩存 1 小時(適用于靜態資源)
header('Cache-Control: public, max-age=3600');
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');
四、文件操作相關
1. 文件下載
$filePath = '/path/to/file.zip';header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
header('Content-Length: ' . filesize($filePath));readfile($filePath);
exit;
2. 斷點續傳支持
header('Accept-Ranges: bytes');
header('Content-Length: ' . filesize($filePath));
五、安全相關頭部
1. 防止點擊劫持
header('X-Frame-Options: DENY'); // 或 SAMEORIGIN
2. 內容安全策略(CSP)
header("Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com");
3. 禁用 MIME 類型嗅探
header('X-Content-Type-Options: nosniff');
六、跨域資源共享(CORS)
1. 簡單跨域請求
header('Access-Control-Allow-Origin: *'); // 允許所有域名(慎用)
header('Access-Control-Allow-Origin: https://trusted-site.com'); // 指定域名
2. 預檢請求處理
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');header('Access-Control-Allow-Headers: Content-Type, Authorization');header('Access-Control-Max-Age: 86400'); // 緩存預檢結果 24 小時exit;
}
七、Cookie 操作
1. 設置 Cookie
setcookie('user_token', // Cookie 名稱'abc123xyz', // 值time() + 3600, // 過期時間(1 小時)'/', // 有效路徑'.example.com', // 域名(支持子域名)true, // 僅 HTTPS 傳輸true // 禁止 JavaScript 訪問(HttpOnly)
);
2. 刪除 Cookie
setcookie('user_token', '', time() - 3600, '/', '.example.com', true, true);
八、高級場景示例
1. 構建 JSON API
try {$data = ['status' => 'success', 'data' => fetchData()];http_response_code(200);
} catch (Exception $e) {$data = ['status' => 'error', 'message' => $e->getMessage()];http_response_code(500);
}header('Content-Type: application/json');
echo json_encode($data, JSON_UNESCAPED_UNICODE);
exit;
2. 強制下載大文件(內存優化)
$file = fopen('large-file.iso', 'rb');header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="large-file.iso"');while (!feof($file)) {echo fread($file, 8192); // 分塊輸出ob_flush();flush();
}fclose($file);
exit;
關鍵注意事項
-
輸出順序問題
- 所有
header()
調用必須在任何實際輸出(包括空格和空行)之前 - 使用
ob_start()
開啟輸出緩沖可避免報錯
- 所有
-
編碼一致性
header('Content-Type: text/html; charset=utf-8'); // 同時設置 PHP 內部編碼 mb_internal_encoding('UTF-8');
-
性能優化
- 避免頻繁設置重復頭部
- 使用
header_remove()
清除不需要的默認頭部
-
安全防護
- 敏感操作后立即調用
session_regenerate_id()
- 使用
header('X-XSS-Protection: 1; mode=block')
啟用瀏覽器 XSS 過濾
- 敏感操作后立即調用
三, PHP模擬 HTTP 請求
一、使用 file_get_contents()
發送請求
適用于簡單 GET/POST 請求,需開啟 allow_url_fopen
配置。
1. 發送 GET 請求
$url = 'https://api.example.com/data?param1=value1¶m2=value2';
$response = file_get_contents($url);
echo $response;
2. 發送 POST 請求(表單數據)
$url = 'https://api.example.com/submit';
$data = ['key1' => 'value1', 'key2' => 'value2'];$options = ['http' => ['method' => 'POST','header' => 'Content-Type: application/x-www-form-urlencoded','content' => http_build_query($data)]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
echo $response;
3. 發送 POST 請求(JSON 數據)
$url = 'https://api.example.com/submit';
$data = json_encode(['name' => 'Alice', 'age' => 30]);$options = ['http' => ['method' => 'POST','header' => "Content-Type: application/json\r\n",'content' => $data]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
echo $response;
二、使用 cURL 擴展
功能更強大,支持 HTTPS、頭部設置、文件上傳等。
1. 基礎 GET 請求
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.example.com/data');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 返回響應內容
$response = curl_exec($ch);
curl_close($ch);
echo $response;
2. 發送 POST 請求(表單數據)
$url = 'https://api.example.com/submit';
$data = ['username' => 'test', 'password' => '123456'];$ch = curl_init();
curl_setopt_array($ch, [CURLOPT_URL => $url,CURLOPT_RETURNTRANSFER => true,CURLOPT_POST => true,CURLOPT_POSTFIELDS => http_build_query($data),CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded']
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
3. 發送 POST 請求(JSON 數據)
$url = 'https://api.example.com/submit';
$data = json_encode(['title' => 'Test', 'content' => 'Hello World']);$ch = curl_init();
curl_setopt_array($ch, [CURLOPT_URL => $url,CURLOPT_RETURNTRANSFER => true,CURLOPT_POST => true,CURLOPT_POSTFIELDS => $data,CURLOPT_HTTPHEADER => ['Content-Type: application/json','Authorization: Bearer abc123xyz']
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
三、處理 HTTPS 與 SSL 驗證
1. 忽略 SSL 證書驗證(僅限測試環境)
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
2. 指定 CA 證書
curl_setopt($ch, CURLOPT_CAINFO, '/path/to/cacert.pem');
四、文件上傳
$filePath = '/path/to/file.jpg';
$data = ['file' => new CURLFile($filePath, 'image/jpeg', 'photo.jpg'),'description' => 'My photo'
];$ch = curl_init();
curl_setopt_array($ch, [CURLOPT_URL => 'https://api.example.com/upload',CURLOPT_POST => true,CURLOPT_POSTFIELDS => $data,CURLOPT_RETURNTRANSFER => true
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
五、處理 Cookies
1. 發送時攜帶 Cookies
curl_setopt($ch, CURLOPT_COOKIE, 'session_id=abc123; user_token=xyz789');
2. 保存響應 Cookies
curl_setopt($ch, CURLOPT_COOKIEJAR, '/path/to/cookies.txt'); // 保存到文件
curl_setopt($ch, CURLOPT_COOKIEFILE, '/path/to/cookies.txt'); // 讀取 Cookies
六、高級配置
1. 設置超時時間載
curl_setopt($ch, CURLOPT_TIMEOUT, 30); // 30 秒超時
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); // 連接超時 10 秒
2. 處理重定向
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 自動跟隨重定向
curl_setopt($ch, CURLOPT_MAXREDIRS, 5); // 最大重定向次數
3. 獲取響應頭信息
curl_setopt($ch, CURLOPT_HEADER, true); // 包含頭信息在輸出中$response = curl_exec($ch);
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($response, 0, $headerSize);
$body = substr($response, $headerSize);echo "Headers:\n$headers\nBody:\n$body";
七、錯誤處理
$ch = curl_init();
// ... 設置選項 ...$response = curl_exec($ch);
if ($response === false) {$error = curl_error($ch);$errno = curl_errno($ch);echo "cURL 錯誤 ($errno): $error";
} else {$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);echo "HTTP 狀態碼: $httpCode\n響應內容:\n$response";
}
curl_close($ch);
八、完整示例:調用 REST API
function callApi($url, $method = 'GET', $data = null, $headers = []) {$ch = curl_init();$options = [CURLOPT_URL => $url,CURLOPT_RETURNTRANSFER => true,CURLOPT_CUSTOMREQUEST => strtoupper($method),CURLOPT_HTTPHEADER => $headers];if ($method !== 'GET' && $data !== null) {$options[CURLOPT_POSTFIELDS] = is_array($data) ? json_encode($data) : $data;}curl_setopt_array($ch, $options);$response = curl_exec($ch);$error = curl_error($ch);$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);curl_close($ch);return ['code' => $httpCode,'data' => json_decode($response, true),'error' => $error];
}// 調用示例
$result = callApi('https://api.example.com/users','POST',['name' => 'Alice', 'email' => 'alice@example.com'],['Content-Type: application/json', 'Authorization: Bearer token123']
);print_r($result);
注意事項
- 安全建議
- 生產環境務必啟用 SSL 證書驗證
- 敏感數據(如 API 密鑰)不要硬編碼在代碼中
- 對用戶輸入做嚴格過濾
- 性能優化
- 復用 cURL 句柄(使用
curl_init()
一次,多次請求) - 設置合理的超時時間
- 復用 cURL 句柄(使用
- 第三方庫推薦
如需更復雜功能,可使用:- Guzzle HTTP:
composer require guzzlehttp/guzzle
- Symfony HTTP Client:
composer require symfony/http-client
- Guzzle HTTP: