我知道您可以使用header('Location: next.php')
以及其他可能的解决方案来完成此操作,但必须在将任何输出发送到客户端之前使用它。我的问题是为什么 PHP 在任何给定时间都不支持页面重定向功能。我只想知道为什么,对解决方案或解决方法不感兴趣。谢谢。
8 回答
因为它实际上是一个客户端功能。这就是您HTML
用来完成此任务的原因。
<META http-equiv="refresh" content="5;URL=http://www.google.com">
PHP 是一种服务器端语言,因此在显示在客户端之前,所有内容都在服务器上进行了预处理......因此,任何 PHP 重定向都应该在任何内容发送到客户端之前发生......在页面加载后需要完成的重定向有发生在客户端 JS 或元刷新代码中。
您必须记住这PHP
是一种服务器端语言。因此,一旦页面加载到客户端的浏览器上,您就无法再控制或访问它。在内容离开服务器后,将无法操纵客户端浏览器窗口的加载、重新加载或重新定位。
原因是因为您引用的函数使用 HTTP 标头发送重定向。
HTTP 标头必须(顾名思义)在响应开始时发送,在任何实际内容之前。
一旦您发送了任何内容,您就不能再发送任何 HTTP 标头。这就是为什么它不起作用。
可以使用该ob_start()
函数将 PHP 设置为不发送任何内容。如果这样做,您将能够在生成输出后发送重定向。这是有效的,因为 HTTP 内容不是使用这种方法发送的,因此发送 HTTP 标头仍然有效。
但是在正常情况下,发送任何正文内容意味着您不能发送任何后续标头。
还有其他可以在页面正文内容中触发重定向的 Javascript 方法,但它们的工作方式完全不同,并且不能作为标准 PHP 函数使用。通过将相关的 javascript 代码作为 HTTP 内容输出的一部分来调用它们很容易。
这是因为要进行 HTTP 重定向,重定向必须在响应标头中。标题位于内容正文之前。一旦输出了任何正文,您就无法发送标头。
因为您在开始发送正文后无法发送标题。
- HTTP 标头
- HTTP 正文
而已。一旦您的脚本输出任何内容,PHP 就会开始发送响应(即标题和正文的一部分)。因此,不可能在任何给定时间在代码中添加重定向标头。
因为 HTTP 不支持它。
HTTP 协议本质上将响应分为 3 个部分:
- 描述请求结果的数字代码和描述(即。
200 OK
) - 描述它将发送什么的标头
- 回复内容
PHP 认为 1 和 2 都是标头,但 HTTP 在开始刷新内容后根本无法添加新标头(步骤 3)。因此,您必须在发送内容之前指定重定向,因为这意味着响应代码将更改为 3xx 范围内的数字,并Location
添加一个标头。
您可以在一定程度上通过使用输出缓冲强制 PHP 在生成内容时不立即发送内容来缓解这种行为:
ob_start();
在此调用之后,所有输出都被缓冲,直到您明确刷新它或脚本结束,允许您仍然更改标头。但是,为此使用它是一种不好的做法,在开始渲染输出之前确定请求的结果要好得多。
- 在 php.ini 中启用 output_buffering - 然后你可以使用 Location: 任何你想要的地方
- 使用框架——他们通常有一个功能
- “手动”使用缓冲:ob_start(); ob_get_contents() 等。然后您可以在代码中使用重定向 ANYWHERE
您还可以使用 JS 解决方案:
<script>location.href="/";</script>
甚至是 HTML 中的元重定向。只需使用 PHP 输出该 HTML/JS 代码,它就会进行重定向。