header() 是 PHP 直接操作 HTTP 協議層的核心函數,掌握它等於掌握了「與瀏覽器對話」的主動權。本文系統整理了開發中最高頻的 Header 使用場景,並解釋底層原理與最佳實踐。
鐵律:header() 必須在任何實際輸出(echo、HTML 空白、BOM 頭)之前調用。PHP 5.4+ 可配合 ob_start() 緩衝區解決順序問題,但建議架構層面就避免過早輸出。
<?php
// 正常響應(默認 200,通常可省略)
header('HTTP/1.1 200 OK');
// 404 未找到
header('HTTP/1.1 404 Not Found');
// 301 永久重定向(SEO 傳遞權重)
header('HTTP/1.1 301 Moved Permanently');
header('Location: https://new-domain.com/');
// 302 臨時重定向(默認 Location 行為)
header('Location: /login.php');
// 延遲跳轉(10 秒後跳轉)
header('Refresh: 10; url=https://example.com');
?>
提示:Location 絕對 URL 更安全,相對路徑在某些代理下可能異常。
<?php
// 網頁編碼(必須在 HTML 前發送)
header('Content-Type: text/html; charset=utf-8');
// API 接口標準
header('Content-Type: application/json; charset=utf-8');
// 文件下載通用
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="report.xlsx"');
header('Content-Transfer-Encoding: binary');
readfile('report.xlsx'); // 輸出文件流
// 特定文件類型
header('Content-Type: image/jpeg'); // JPG
header('Content-Type: application/pdf'); // PDF
header('Content-Type: application/zip'); // ZIP
header('Content-Type: text/css'); // CSS
header('Content-Type: application/javascript'); // JS (推薦)
?>
<?php
// 完全禁用緩存(動態頁面、敏感數據)
header('Cache-Control: no-cache, no-store, max-age=0, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // HTTP/1.0 兼容
header('Pragma: no-cache'); // HTTP/1.0 兼容
// 強制緩存 1 小時(靜態資源)
header('Cache-Control: public, max-age=3600');
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');
// 協商緩存(配合 Last-Modified / ETag)
$lastMod = filemtime('data.json');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastMod) . ' GMT');
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $lastMod) {
header('HTTP/1.1 304 Not Modified');
exit;
}
?>
<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('HTTP/1.1 401 Unauthorized');
header('WWW-Authenticate: Basic realm="Admin Area"');
exit('需要登錄');
}
// 驗證 $_SERVER['PHP_AUTH_USER'] / $_SERVER['PHP_AUTH_PW']
?>
<?php
// 防點擊劫持
header('X-Frame-Options: DENY');
// 或允許同源
// header('X-Frame-Options: SAMEORIGIN');
// 防 MIME 嗅探
header('X-Content-Type-Options: nosniff');
// XSS 保護(舊瀏覽器)
header('X-XSS-Protection: 1; mode=block');
// 內容安全策略 (CSP) 核心防線
header("Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' https://cdn.example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:;");
// HSTS 強制 HTTPS(生產環境謹慎開啟,需確保全站 HTTPS)
// header('Strict-Transport-Security: max-age=31536000; includeSubDomains; preload');
// Referrer Policy
header('Referrer-Policy: strict-origin-when-cross-origin');
?>
false(如多個 Set-Cookie)。urlencode() 編碼並兼容瀏覽器差異(IE/Edge 需 filename* RFC 5987 格式)。readfile(),改用分塊輸出 fread() 循環 + flush()。header() 雖是簡單函數,但背後涉及 HTTP 協議全棧知識。建議將常用 Header 封裝為 Response 類或中間件(如 Laravel Response::json()、Symfony Response),統一管理,避免控制器中散落底層協議細節。