HOWTO · PHP
PHP 中的重定向
本教程演示了如何将用户从页面重定向到 PHP 中的其他页面
本页内容
在 PHP 中重定向请求时,先用 header() 发送 Location 响应头,再停止脚本;这必须发生在脚本输出 HTML 或其他内容之前。下面的示例会将浏览器导航到目标 URL。将 PHP 文件放在本地 Web 服务器上,再用浏览器打开,即可查看导航效果。
使用 PHP 的 header() 函数重定向到 URL
header() 函数会发送 HTTP 响应头。重定向时,头字段是 Location,其值为目标 URL。PHP 必须在发送任何响应正文内容之前发送此头,包括 PHP 标签外的空白字符。请将重定向代码放在请求处理程序靠前的位置,置于模板或页面输出之前。
这个独立示例将目标 URL 存放在变量中。响应准备好后,exit 会结束当前请求,避免页面其余部分继续执行,让行为看起来像重定向没有发生一样。提供的运行检查已成功执行此示例,且没有产生标准输出;重定向信息通过 HTTP 响应传递,而不是作为文本打印出来。通过本地 Web 服务器在浏览器中打开 PHP 文件时,浏览器应会导航到示例中的目标地址。
<?php
$url = 'https://example.com/';
header('Location: ' . $url);
exit;
?>
请使用应用允许跳转到的 URL。如果目标地址来自请求数据,请用允许列表进行验证,或根据可信的应用路由构造目标地址;将任意用户输入直接用于重定向,可能会把访客带到非预期的网站。若要跳转到同一应用内的路由,通常使用 /account/ 这样的路径就足够了。
使用 HTTP 状态码创建 PHP 重定向辅助函数
可复用的 redirect 辅助函数可以同时接收目标地址和响应状态码。header() 的第三个参数是状态码;第二个参数用于控制是否替换先前同名的头字段。下面的辅助函数默认使用 302,这通常表示临时重定向;如果路由有需要,也可以传入其他状态码。
<?php
function redirect(string $url, int $statusCode = 302): void
{
header('Location: ' . $url, true, $statusCode);
exit;
}
redirect('https://example.com/', 301);
?>
示例传入 301,表示目标地址已永久更改。只有在迁移确实会长期生效时才使用此状态码;浏览器和其他客户端可能会记住永久重定向。302 表示临时重定向;如果目标地址可能变化,它通常是更合适的默认值。PHP 的 header() 手册介绍了该函数的参数,MDN 的 301 参考资料说明了永久状态码。
提供的运行检查已成功执行此辅助函数示例,且没有产生标准输出;重定向状态码和 Location 头字段属于 HTTP 响应的一部分,不会作为文本打印出来。请通过本地 Web 服务器运行 PHP 文件,以观察浏览器导航。函数设置响应头后会结束请求。在实际应用中,调用辅助函数前应验证 URL,并根据迁移是临时还是永久选择相应的状态码。Location 头字段和状态码都属于 HTTP 响应,因此浏览器收到页面正文之前就能处理这种重定向。
将 JavaScript 用作客户端重定向后备方案
如果无法使用服务器端重定向,页面可以通过 window.location 请求浏览器导航。这属于客户端导航:PHP 发送页面内容,浏览器再运行脚本。它不是 PHP 输出缓冲,也不会将 HTTP 响应变成服务器端重定向。此方式还要求启用 JavaScript;如果服务器能在发送页面前确定目标地址,请使用 PHP 的 header() 方法。
下面的浏览器页面代码片段展示了这种后备方案。将它加入本地 Web 服务器能够提供的页面,再用启用了 JavaScript 的浏览器打开该页面,即可导航到目标地址。此片段作为浏览器端源码提供,本文未执行过它。
<script>
window.location = "https://example.com/";
</script>
由于这段代码在浏览器中运行,它无法将 301 之类的 HTTP 重定向状态码加入浏览器已经收到的响应中。请固定目标地址,或验证用于构造目标地址的任何值,做法与服务器端重定向相同。只有在客户端导航适合该页面时才使用此后备方案;停用了 JavaScript 的访客仍会停留在原页面。