重定向本质是服务器向浏览器发送特定 HTTP 状态码(301/302/404 等)和 Location 响应头。PHP 通过 header() 函数发送原始 HTTP 头实现。状态码由 HTTP 协议标准定义,无需纠结数字含义。
<?php
header('HTTP/1.1 301 Moved Permanently');
header('Location: https://www.example.com/');
exit(); // 关键:阻止后续代码执行
?>
<?php
$http_protocol = $_SERVER['SERVER_PROTOCOL']; // 获取客户端协议版本
if ($http_protocol !== 'HTTP/1.1' && $http_protocol !== 'HTTP/1.0') {
$http_protocol = 'HTTP/1.0'; // 兜底
}
header("$http_protocol 301 Moved Permanently");
$new_url = 'https://www.example.com/';
header("Location: $new_url");
exit();
?>
<?php
// 默认即为 302 Found,无需显式发送状态行
header('Location: https://www.example.com/');
exit();
?>
注意:若需明确语义,可发送 header('HTTP/1.1 302 Found');,但通常直接 Location 即可。
<?php
header('HTTP/1.1 404 Not Found');
exit();
// 可选:include('404.html'); 展示友好页面
?>
# 单页面永久重定向
Redirect 301 /old/old.htm https://www.example.com/new.htm
# 目录永久重定向
Redirect permanent /one https://example.com/two
# 正则匹配:将 .gif 重定向到对应 .jpg
RedirectMatch 301 (.*).gif$ https://www.example.com/images/$1.jpg
Options +FollowSymLinks
RewriteEngine on
# 强制非 www 跳转 www(永久)
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
# HTTPS 强制跳转
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
| 要点 | 说明 |
|---|---|
| header() 必须在输出前 | 任何 echo、空白字符、BOM 头、HTML 标签都会导致 "Headers already sent" 错误。 |
| exit()/die() 必不可少 | 防止脚本继续执行,浪费资源且可能产生非预期输出。 |
| Location 使用绝对 URL | RFC 7231 要求绝对 URI;虽然浏览器兼容相对路径,但最佳实践用完整 URL。 |
| 301 会被浏览器缓存 | 测试时用 302,确认无误再改 301;清除缓存需清理浏览器缓存或用无痕模式。 |
| SEO 影响 | 301 传递链接权重,搜索引擎更新索引;302 不传递权重,适合临时维护、A/B 测试。 |
# 301 永久
rewrite ^/old/(.*)$ https://www.example.com/$1 permanent;
# 302 临时
rewrite ^/temp/(.*)$ https://www.example.com/new/$1 redirect;