PHP header() 函数(保姆级教程)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战(已更新的所有项目都能学习) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新开坑项目:《Spring AI 项目实战》 正在持续爆肝中,基于 Spring AI + Spring Boot 3.x + JDK 21..., 点击查看 ;
- 《从零手撸:仿小红书(微服务架构)》 已完结,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观
前言
在 Web 开发中,HTTP 协议的头部信息(HTTP Headers)如同快递包裹上的地址标签,决定了数据传输的方向、格式和安全性。而 PHP 的 header()
函数,正是开发者控制这些“标签”的核心工具。无论是实现页面跳转、设置内容类型,还是增强安全性,PHP header() 函数
都是不可或缺的“瑞士军刀”。本文将从零开始,通过通俗的比喻、实用案例和代码示例,帮助读者系统掌握这一功能强大的函数。
一、HTTP Headers 的基础概念:为什么需要 header() 函数?
1.1 HTTP 协议与头部信息
HTTP(超文本传输协议)是 Web 的通信基础。每当浏览器请求页面时,服务器会通过 响应头(Response Headers) 和 响应体(Response Body) 返回数据。例如:
- 响应头:包含数据类型、缓存策略、安全策略等元信息;
- 响应体:实际的 HTML、JSON 或图片内容。
header()
函数的作用,就是让开发者在 PHP 中动态生成这些响应头,从而控制 HTTP 交互的细节。
比喻:
想象快递员送包裹时,必须在出发前贴好收件人地址、物品类型标签。若标签贴错或未及时粘贴,包裹可能被退回或损坏。HTTP 头的作用类似——如果未正确设置,浏览器可能无法正确解析返回的数据。
1.2 header() 函数的语法与基本用法
语法结构
header(string $header, bool $replace = true, int $http_response_code = 0): bool
- 参数说明:
$header
:要发送的 HTTP 头内容,例如Content-Type: application/json
。$replace
(可选):若为true
(默认),则替换已有相同名称的头;若为false
,则追加。$http_response_code
(可选):设置 HTTP 状态码(如 200、404)。
基础示例:设置内容类型
<?php
// 设置响应内容为 JSON 格式
header('Content-Type: application/json');
echo json_encode(['message' => 'Hello World']);
效果:浏览器会识别此响应为 JSON 数据,而非默认的 HTML。
二、header() 函数的常见使用场景
2.1 场景一:页面重定向(Redirect)
页面跳转是 Web 开发中高频需求。通过 Location
头,可以实现无缝跳转。
代码示例:302 临时跳转
<?php
// 跳转到登录页面
header('Location: /login.php');
exit(); // 必须退出脚本,避免后续代码执行
注意:
exit()
是关键!若未退出,后续代码可能输出内容,导致 HTTP 头无法发送。- 默认使用 302 临时重定向,若需永久跳转,可显式设置状态码:
header('Location: /new-page.php', true, 301);
案例:登录后跳转
if ($user->is_logged_in()) {
header('Location: /dashboard.php');
exit();
}
2.2 场景二:控制文件下载
通过设置 Content-Disposition
头,可以让浏览器将响应内容视为文件下载,而非直接显示。
代码示例:强制下载 PDF 文件
<?php
$file_path = 'reports/sales_report.pdf';
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="sales_report.pdf"');
readfile($file_path); // 读取并输出文件内容
关键点:
attachment
表示“下载”,若改为inline
,则浏览器会尝试直接显示文件(如图片或 PDF 预览)。- 需结合
readfile()
或fpassthru()
实际输出文件内容。
2.3 场景三:设置响应状态码
通过第三个参数或直接声明状态码,可以自定义 HTTP 状态码,例如:
代码示例:返回 404 错误
<?php
// 方法一:直接声明
header('HTTP/1.1 404 Not Found');
// 方法二:使用第三个参数
header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found', true, 404);
常见状态码应用场景:
状态码 | 含义 | 典型用途 |
---|---|---|
200 | 成功 | 默认响应 |
301 | 永久重定向 | 网址迁移 |
403 | 禁止访问 | 无权限访问资源 |
404 | 未找到资源 | 路径不存在 |
500 | 服务器内部错误 | 代码异常或配置错误 |
2.4 场景四:防止缓存
通过设置 Cache-Control
和 Expires
头,可以控制浏览器缓存行为:
代码示例:禁用缓存
<?php
// 禁止所有缓存
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // 设置过期时间为过去时间
三、header() 函数的注意事项与进阶技巧
3.1 规则一:输出内容前调用 header()
HTTP 头必须在任何输出(包括 HTML、空格、echo
、print
)之前发送。否则会触发致命错误:
Warning: Cannot modify header information - headers already sent...
解决方案:
- 确保 PHP 代码在 HTML 内容之前;
- 检查是否有空格或
echo
在 header() 之前; - 使用
ob_start()
启用输出缓冲区(但非根本解决方式)。
比喻:
快递员必须在出发前贴好地址标签,否则快递站无法发货。
3.2 规则二:避免头信息冲突
当使用 $replace = false
时,可能会导致重复的头信息。例如:
header('Set-Cookie: theme=dark', false); // 第一次
header('Set-Cookie: theme=light', false); // 第二次
此时会发送两个 Set-Cookie
头,可能导致不可预期的结果。
3.3 安全相关头设置
通过 header()
可以增强应用的安全性,例如:
3.3.1 防止 XSS 攻击
// 启用内容安全策略(Content Security Policy)
header("Content-Security-Policy: default-src 'self'; script-src 'self' cdn.example.com");
3.3.2 防止点击劫持(X-Frame-Options)
// 禁止页面被嵌入到其他网站的 iframe 中
header('X-Frame-Options: DENY');
3.4 高级技巧:自定义 HTTP 头
开发者可自定义头信息传递元数据,例如:
header('X-Custom-Header: My-App-Version-2.0.1');
四、实战案例分析
案例 1:登录后跳转与错误处理
<?php
session_start();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = $_POST['username'];
$password = $_POST['password'];
if (validate_user($username, $password)) {
$_SESSION['user'] = $username;
header('Location: /dashboard.php'); // 登录成功后跳转
exit();
} else {
header('HTTP/1.1 401 Unauthorized'); // 返回 401 状态码
echo 'Invalid credentials';
exit();
}
}
案例 2:文件下载器(带进度条)
<?php
$file_path = 'uploads/' . $_GET['file'];
if (file_exists($file_path)) {
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($file_path) . '"');
header('Content-Length: ' . filesize($file_path));
// 支持断点续传
header('Accept-Ranges: bytes');
readfile($file_path);
} else {
header('HTTP/1.1 404 Not Found');
echo 'File not found';
}
案例 3:防止跨站请求伪造(CSRF)
<?php
// 在表单页面设置 Token
session_start();
$token = bin2hex(random_bytes(32));
$_SESSION['csrf_token'] = $token;
// 在表单 HTML 中嵌入 Token
echo '<input type="hidden" name="csrf_token" value="' . $token . '">';
// 在处理请求时验证 Token
if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
header('HTTP/1.1 403 Forbidden');
exit();
}
五、结论
PHP header() 函数
是开发者控制 HTTP 交互的核心工具。通过本文的学习,读者应能掌握其基本语法、常见场景、注意事项及安全实践。无论是实现页面跳转、文件下载,还是增强应用安全性,header()
函数都能提供高效且灵活的解决方案。
建议读者:
- 通过实际项目练习重定向、文件下载等场景;
- 参考 RFC 文档(如 RFC 9110 )深入了解 HTTP 头的规范;
- 结合 PHP 的
http_response_code()
函数简化状态码设置。
掌握 PHP header() 函数
,你将能更精准地控制 Web 应用的交互逻辑,为用户提供更流畅、安全的体验。