今天咱们聊聊PHP里那个看似简单实则暗藏杀机的header location跳转。这东西就像你追女神时发的微信定位,发对了能约到咖啡馆,发错了直接进黑名单。
先来个标准姿势热热身:
php
header('Location: https://www.example.com');
exit;
看到没?重点在exit。我见过太多人写完header就以为完事了,结果后面的代码继续执行,跟拉肚子时以为完事了结果又来个回马枪一样尴尬。
最常见的翻车现场是输出后才调header:
php
echo '开始跳转啦';
这时候浏览器会亲切地告诉你:"Cannot modify header information - headers already sent"。翻译成人话就是:你都开始脱裤子了才说要换场地?
解决方案有三:
1. 用ob_start()开启输出缓冲
2. 检查headers_sent()再决定是否跳转
3. 把header代码提到所有输出之前
我一般用方案3,就像上厕所前先确认洗手间位置一样自然。
说到相对路径和绝对路径,这里有个经典坑:
php
header('Location: /admin'); // 可能跳到你爹都找不到的路径
header('Location: https://yoursite.com/admin'); // 这才是亲儿子
有些框架喜欢玩路径魔术,结果header跳转时直接表演消失术。所以我的原则是:能用绝对URL就别装逼。
关于HTTP状态码,你们知道302和301的区别吗?就像临时工和正式工的区别:
php
header('Location: https://example.com', true, 301); // 永久搬家
SEO老司机都知道301能让搜索引擎更新地址,302就是个过客。我曾经用302做永久跳转,结果被SEO按在地上摩擦了三个月。
现在说个高级玩法:延迟跳转。有时候需要先显示"正在转向新页面..."再跳转:
php
header("Refresh: 5; url=https://example.com");
echo '5秒后自动跳转,如未跳转请点击这里';
这招在支付完成页特别实用,就像吃完火锅给你5秒后悔时间。
关于安全有个血泪教训:永远验证跳转目标!有次我直接用了$_GET参数做跳转:
php
header('Location: ' . $_GET['url']);
结果被黑客用来做钓鱼跳转,差点把公司内裤都赔光。现在我都这么干:
$allowedDomains = ['example.com', 'trusted.com'];
$url = parse_url($_GET['url']);
if (!in_array($url['host'], $allowedDomains)) {
die('你小子想干?');
}
说到性能,有个冷知识:header跳转比meta refresh快大约300ms。虽然对普通人来说就是眨眼的功夫,但对电商网站来说,这300ms可能值一辆宝马。
跨域跳转时可能会遇到CORS问题,这时候可以这样:
php
header('Location: https://otherdomain.com');
header('Access-Control-Allow-Origin: *');
不过现在浏览器越来越严格,最好还是让后端API配合处理。
有个奇葩案例:某次我用header跳转下载文件,结果IE浏览器死活不认:
php
header('Location: /downloads/file.zip');
后来发现得这么写:
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="file.zip"');
readfile('/path/to/file.zip');
exit;
IE这货就像个矫情的前任,得用特别的方式对待。
关于缓存有个坑:有时候浏览器会缓存301跳转。测试时明明改了代码,浏览器却死活不更新。解决方案:
php
header('Location: /new-page', true, 302); // 测试用302
// 上线后再改为301
最后说个终极技巧:链式跳转追踪。有时候需要记录跳转路径:
php
// 跳转前先记录
$trackingId = log_redirect($_SERVER['REQUEST_URI'], '/target');
header('Location: /target?track='.$trackingId);
这样就能知道用户从哪来的,就像给每个访客发个GPS追踪器。
记住,header location用得好是神器,用不好就是自爆按钮。写完header后一定要:
1. 马上exit或die
2. 检查是否有输出
3. 验证目标URL
4. 选对状态码
否则就会像我去年那样,半夜接到老板电话:"为什么我们的用户都被跳转到小黄站了?" 这种经历,一次就够记一辈子。