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-ControlExpires 头,可以控制浏览器缓存行为:

代码示例:禁用缓存

<?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、空格、echoprint)之前发送。否则会触发致命错误:

Warning: Cannot modify header information - headers already sent...  

解决方案:

  1. 确保 PHP 代码在 HTML 内容之前;
  2. 检查是否有空格或 echo 在 header() 之前;
  3. 使用 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() 函数都能提供高效且灵活的解决方案。

建议读者

  1. 通过实际项目练习重定向、文件下载等场景;
  2. 参考 RFC 文档(如 RFC 9110 )深入了解 HTTP 头的规范;
  3. 结合 PHP 的 http_response_code() 函数简化状态码设置。

掌握 PHP header() 函数,你将能更精准地控制 Web 应用的交互逻辑,为用户提供更流畅、安全的体验。

最新发布