为什么在PHP中,ob_start()必须在session_start()之前才能正常工作?

11

我认为这是不合理的。

实际上,为什么会有这样的规定呢?


6
坦白说,我从未听说过这样的规定! - mauris
6个回答

15
在“正常情况”下,我认为在调用session_start之前不需要调用ob_start,反之亦然。
引用session_start的手册页面

当启用trans-sid时,session_start()将为URL重写注册内部输出处理程序。如果用户使用ob_gzhandler或类似函数与ob_start()一起使用,则输出处理程序的顺序对于正确的输出很重要。例如,用户必须在会话开始之前注册ob_gzhandler。

但这是某种特殊情况:问题在于输出处理程序的顺序很重要:如果您希望一个处理程序修改另一个处理程序所做的事情,则它们必须按“正确”的顺序执行。
一般来说,如果您不使用这种处理程序(例如,Apache和mod_deflate在压缩输出方面做得很好),那么唯一重要的事情是在调用session_start之前不能发送标头(因为根据您的配置,session_start会发送作为HTTP标头传递的cookie)。
并且只要有任何输出,即使是<?php ?>标记外的一个空格,标头也会立即发送 - 即,只要有任何输出。
注意:如果您正在使用基于cookie的会话,则必须在向浏览器输出任何内容之前调用session_start()。
ob_start表示PHP必须缓冲数据:
此函数将打开输出缓冲。当输出缓冲处于活动状态时,脚本不发送任何输出(除了标题),而是将输出存储在内部缓冲区中。
通过这种方式,输出不会在您实际上说“发送数据”之前发送。这意味着标题不会立即发送-这意味着即使应该有输出,如果没有使用ob_start,则稍后也可以调用session_start。
希望这样能让事情更加清楚...

6
如果默认情况下您的output_bufferingOff,并且不幸地向客户端发送了一个字节的数据,则您的HTTP标头已经被发送。这有效地防止了session_start()将cookie标头传回客户端。通过调用ob_start(),您可以启用缓冲,从而延迟发送http标头。

0

在发送任何头文件之前,应该调用session_start()。ob_start()可以暂时抑制输出,您可以打破这个规则。通常情况下,在顶部使用ob_start()是一种快速修复方法,以防您正在调试某些未知内容;在此之下的所有内容都如预期工作(不仅仅是按照编写的方式处理);我更喜欢在session_start()之后再使用ob_start()。


0

session_start() 在启用 trans-sid 时会注册内部输出处理程序以进行 URL 重写。如果用户使用 ob_gzhandler 或类似函数与 ob_start() 一起使用,则输出处理程序的顺序对于正确的输出非常重要。

例如,用户必须在会话开始之前注册 ob_gzhandler

但这是某种特殊情况。问题在于,这里输出处理程序的顺序很重要。如果您希望一个处理程序修改另一个处理程序所做的事情,则它们必须按照“正确”的顺序执行。

通常,如果您不使用此类处理程序(例如 Apache 和 mod_deflate 在压缩输出方面表现出色),那么唯一重要的事情就是在调用 session_start 之前不能发送标头(因为根据您的配置,session_start 发送作为 HTTP 标头传递的 cookie)。

并且只要有任何数据需要发送,即使是在 <?php ?> 标记之外的一个空格,标头也会立即发送:

注意:如果您正在使用基于cookie的会话,必须在任何内容输出到浏览器之前调用session_start()

ob_start表示PHP必须缓冲数据:

此函数将打开输出缓冲。当输出缓冲处于活动状态时,脚本不会发送任何输出(除了标头),而是将输出存储在内部缓冲区中。

这样,输出不会在您实际上说“发送数据”之前发送。这意味着标头不会立即发送——这意味着稍后可以调用session_start,即使应该有输出,如果没有使用ob_start


0

session_start 可能会修改 HTTP 标头,如果设置了某些配置选项。例如,session.use_cookies 就需要设置/修改 Set-Cookie 标头字段。

修改 HTTP 标头要求在发送第一个输出之前没有向客户端发送任何输出,因为 HTTP 标头 是在第一个输出之前发送的。

因此,您可以确保在调用 session_start 之前没有任何输出。或者使用 输出缓冲控制 来缓冲输出,以便即使已经有输出,也可以修改 HTTP 标头。


0
在PHP中,ob_start()用于启动输出缓冲。输出缓冲捕获发送到浏览器的所有输出并将其存储在缓冲区中,允许您在将其发送到浏览器之前对其进行操作。
在PHP中使用会话时,重要的是在启动会话之前调用ob_start(),因为会话依赖于cookie,这些cookie作为HTTP标头的一部分发送到浏览器。如果在会话开始之前已经向浏览器发送了任何输出,则标头已经被发送,将无法设置会话cookie。
通过在启动会话之前调用ob_start(),生成会话之前生成的任何输出都将被缓冲区捕获,并且不会发送到浏览器。这使得会话cookie可以正确设置,即使已经生成了一些输出。
总之,在PHP中,ob_start()对于会话是必需的,因为它确保即使在会话开始之前有输出生成,也可以正确发送标头。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接