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

时间:2009-09-20 13:13:09

标签: php session ob-start

我认为这不合理。

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

5 个答案:

答案 0 :(得分:13)

在“正常情况”中,我认为不必在ob_start之前调用session_start - 也不要以其他方式调用。

引用manual page of session_start,但是:

  

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

但这是一种特殊情况:在这里,输出处理程序的顺序很重要:如果你想让一个处理程序修改另一个处理程序,它们必须在“正确”中执行顺序。


通常,如果您不使用那种处理程序(例如,Apache和mod_deflate在压缩输出方面做得很好),唯一重要的是标题在致电session_start 之前不得发送(因为,根据您的配置,session_start会发送Cookie,这些Cookie会作为HTTP标头传递)

一旦必须发送任何数据,就会发送标题 - 即,只要有任何输出,即使是<?php ?>标记之外的一个空格:

  

注意:如果您使用的是基于cookie的   会议,你必须打电话   session_start()在任何事情之前   输出到浏览器。

ob_start表示PHP必须缓冲数据:

  

此功能将变为输出   缓冲。输出缓冲   处于活动状态,没有从中发送输出   相反,脚本(标题除外)   输出存储在内部   缓冲液中。

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


希望这会让事情变得更清晰......

答案 1 :(得分:5)

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

答案 2 :(得分:0)

如果设置了某些配置选项,

session_start可能希望修改HTTP标头。例如,session.use_cookies需要设置/修改 Set-Cookie 标头字段。

修改HTTP标头要求没有任何输出已经发送到客户端,因为在发送第一个输出之前发送了HTTP header

因此,要么确保在调用session_start之前绝对没有输出。或者使用output buffering control缓冲输出,以便即使已经有输出也可以修改HTTP标头。

答案 3 :(得分:0)

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

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

但这是某种特殊情况。在这里,输出处理程序的顺序很重要。如果你想让一个处理程序修改另一个处理程序,它们必须以“正确”的顺序执行。

通常,如果你不使用那种处理程序(例如,Apache和mod_deflate在压缩输出方面做得很好),唯一重要的是不得发送标题在您致电session_start之前(因为,根据您的配置,session_start会发送Cookie,这些Cookie会作为HTTP标头传递)。

一旦必须发送任何数据,就会发送标题 - 即,只要有任何输出,即使是<?php ?>标记之外的一个空格:

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

ob_start表示PHP必须缓冲数据:

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

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

答案 4 :(得分:0)

在session_start();应在任何标头发送之前调用。 ob_start()将抑制输出一段时间,您可以破坏此规则。通常,顶部的ob_start()是一个快速修复,以防您调试未知的东西;下面的所有内容都按预期工作(不仅仅是书面形式;-))。我更喜欢稍后使用ob_start()到s​​ession_start()。