为什么ob_start()必须先于session_start()才能在PHP中工作?

为什么ob_start()必须先于session_start()才能在PHP中工作?,php,session,ob-start,Php,Session,Ob Start,我认为这不合理 为什么它实际上是这样一个规则?在“正常情况下”,我不认为必须在会话开始之前调用ob\u start——也不认为必须在会话开始之前调用ob\u start 不过,引用以下的话: 会话_start()将注册内部 用于URL重写的输出处理程序 已启用trans sid。如果用户使用 带有ob_start()的ob_gzhandler或类似程序, 输出处理程序的顺序为 对于正确的输出很重要。对于 例如,用户必须注册 在会话开始之前执行ob_gzhandler 但这是一种特殊情况:这里的问

我认为这不合理

为什么它实际上是这样一个规则?

在“正常情况下”,我不认为必须在
会话开始之前调用
ob\u start
——也不认为必须在会话开始之前调用
ob\u start

不过,引用以下的话:

会话_start()将注册内部 用于URL重写的输出处理程序 已启用trans sid。如果用户使用 带有ob_start()的ob_gzhandler或类似程序, 输出处理程序的顺序为 对于正确的输出很重要。对于 例如,用户必须注册 在会话开始之前执行ob_gzhandler

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


通常,如果您不使用这种处理程序(例如Apache,在压缩输出方面做得很好),唯一重要的是在调用
session\u start
(因为,根据您的配置,
session\u start
发送cookie,这些cookie作为HTTP头传递)

只要有任何数据需要发送,就会发送头文件,也就是说,只要有任何输出,即使是
标记之外的一个空格:

注意:如果您使用的是基于cookie的 会话,你必须打电话 会话_start(),然后执行任何操作 输出到浏览器

ob_start
表示PHP必须缓冲数据:

此函数将打开输出 缓冲打开。当输出缓冲时 处于活动状态时,未从发送任何输出 改为使用脚本(标题除外) 输出存储在一个内部存储器中 缓冲区

这样,在您自己实际说“发送数据”之前,不会发送输出。这意味着不会立即发送标题——这意味着以后可以调用
session\u start
,即使没有使用
ob\u start
,也应该有输出



希望这能让事情变得更清楚一点…

如果默认情况下您的
输出缓冲
关闭的
,并且您不幸将一个字节的数据发送回客户端,那么您的
HTTP
头已经发送。这有效地阻止了
会话启动()
将cookie头传递回客户端。通过调用
ob\u start()
可以启用缓冲,从而延迟发送http头。

会话\u start
如果设置了某些配置选项,可能需要修改http头。例如,需要设置/修改set cookie头字段

修改HTTP头要求在发送第一个输出之前发送时,没有任何已发送到客户端的输出

因此,您可以确保在调用
会话\u start
之前绝对没有输出。或者使用缓冲区来缓冲输出,以便即使已经有输出,也可以修改HTTP头。

会话\u start()当启用
trans-sid
时,
将为URL重写注册内部输出处理程序。如果用户使用
ob\u gzhandler
或类似的
ob\u start()
,则输出处理程序的顺序对于正确的输出非常重要

例如,用户必须在会话开始之前注册
ob\u gzhandler

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

通常,如果您不使用这种处理程序(例如,Apache和mod_deflate在压缩输出方面做得很好),唯一重要的是,在调用
会话\u start
(因为,根据您的配置,
session\u start
发送cookie,这些cookie作为HTTP头传递)

只要有任何数据需要发送,就会发送头文件,也就是说,只要有任何输出,即使是
标记之外的一个空格:

注意:如果您使用的是基于cookie的会话,则必须在将任何内容输出到浏览器之前调用
session\u start()

ob_start
表示PHP必须缓冲数据:

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


通过这种方式,在您实际说“发送数据”之前不会发送输出。这意味着不会立即发送标题——这意味着即使没有使用
ob\u start
也可以稍后调用session\u start(),即使应该有输出。

session\u start();应该在发送任何标题之前调用。ob\u start()将抑制输出一段时间,您可以打破此规则。通常,顶部的ob_start()是一个快速修复程序,以防您调试未知的内容;下面的所有内容都按预期工作(不仅仅是编写的;-)。我更喜欢稍后使用ob_start()来执行会话_start()。

坦率地说,我还没有听说过这样的规则!