PHP redirect AFTER sending headers?
我有一个函数,如果设置了变量等,它需要重定向页面...
问题是,这个函数在php页面的底部。
这意味着,我输出了很多信息,所以我收到了标题警告。
"警告 - 标题已经由 ..."
有没有办法在发送标头后重定向?
谢谢
- 这不是安全问题。您在 header() 之前执行 print() 或混合使用 <?php?> 和 <html> 标签。
您应该做的是将 ob_start() 放在页面的开头,将 ob_flush() 放在最后。这样你就不会遇到标题已经发送的错误。
查看这些函数以获取进一步参考。
- 末尾的 ob_flush() 是隐式的,可以省略。这样做的好处是,如果您在应用程序控制流中的 ob_flush() 之后添加输出内容,而该函数调用不可见,那么您在几个月后不会意外地回到这个问题。
-
这是 IMO 最干净的解决方案;请注意,这是通过缓冲标题和内容并仅在页面末尾将它们一起发送来工作的。
-
也不是取决于您的输出的大小和该确切页面的访问次数,由于将所有字符串存储到内存中,它确实可能会减慢您的页面速度。
-
它还使渐进式渲染变得不可能。但是我们都在使用 gzip,对吗?对?布勒?
-
@eyelidless:您可以尝试在这里和那里刷新缓冲区。例如在 HTML 头之后。如果数据量不够,大多数浏览器将不会呈现任何内容,所以......是的。 :)
-
@DanMan,如果您使用 gzip(通过 ob_gzhandler 或通过 Apache 或其他方式),无论您刷新缓冲区多少次,我都很确定渐进式渲染是不可能的。而且我认为 gzip 的好处通常超过渐进式渲染的好处。这可以通过分块响应在一定程度上得到缓解,但是应用程序中的架构需要非常低级,排除许多框架和现成的应用程序,甚至那些明确针对开发人员的应用程序,除非它们已经构建为处理它。
-
顺便说一下,在 IIS 上刷新几乎没用,因为 IIS 有它自己的输出缓存,并且一旦它认为它有足够的发送,就发送输出,不像 apache,你告诉它什么。
-
@ITroubs,Apache 也会限制刷新。可能只是比较宽容。
有很多方法,但基本上都是变通方法:
最简单的是meta http-equiv:
1
| <meta http-equiv="Refresh" content="0;http://www.example.com/newlocation"> |
-
当它在 <head> 元素之外时,一些浏览器不会喜欢这个,并进入怪癖模式
或者,您可以尝试使用 JavaScript 重定向:
1
| window.location = 'http://www.example.com/newlocation'; |
-
如果没有 JavaScript,这显然是行不通的。
-
http-equiv 标头必须在文档的前几百个字节内,否则浏览器不会将它们视为 HTTP 标头。
-
@eyelidless:有趣,我不知道。 [需要引用]?
-
@Piskvor,这可能只是一个遗留问题。我在挖掘东西时遇到了麻烦。但我确实记得那天 Microsoft 文档特别警告开发人员在前 N 个字节中放置与 HTTP 等效的元标记,否则它们将不会被视为标头。
-
我会使用 jscript 重定向,或者更好的是进行干净的重构,以便在所有业务逻辑处理完每个数据并做出所有决定之后进行输出,以便在任何输出之前您可以进行重定向,或者如果您由于长时间处理数据而需要做一些输出,可以以这种方式重构它,以便在完成任何输出之前准备好所需的计算。
-
@eyelidloss 很好,如果微软这么说它可能只适用于 IE,如果他们很久以前说过它仍然应该相关,因为 IE 开发团队对 W3C 标准的改变在某种程度上进展缓慢><
-
@ITroubs,是的,它可能仅适用于 IE。但我应该澄清一下,我只记得我记得它是一个 MS 源,它很可能是 A List Apart 或当时任何其他流行的网页设计/开发源。我只记得已经有一段时间了。至于相关性,我不愿意相信,至少,IE 6-8 一开始就可以正确处理极端情况,无论如何,将您的 HTTP 等效元标记向上移动的好处是好的(它提高了响应能力)如果没有别的),如果您无法控制实际的 Web 服务器的 HTTP 标头输出。
-
@ITroubs,关于重定向,Javascript 可能是最不可靠的解决方案。除了重构之外,你为什么要这样做?
-
那么在 OP\\ 的情况下,它可能是唯一的,不是最可靠的,但也是唯一的方法,因为正如您所说,在文档末尾放置 http-equiv 可能没有效果。如果他不能在发送任何输出之前进行合理的重构以发送标头,我认为没有比使用 jscript 更好的方法。如果有误,请纠正我。我真的很愿意学习新事物。
-
@ITroubs,我投票支持输出缓冲。我认为这是一个更可靠的解决方案。编辑:输出缓冲可以通过在应用程序顶部添加一行代码来实现。我认为如果 OP 不能做到这一点,他们就有更大的问题需要与他们的团队一起解决。
-
在许多情况下,元标记可以是一个很好的解决方案。不是很好,但它有效。