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

问题描述:

我不认为这是合理的。为什么ob_start()必须先于session_start()在PHP中工作?

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

+6

坦率地说:我还没有听说过这样的规则! – mauris 2009-09-20 13:20:59

在“正常情况下”,我不认为有ob_startsession_start被称为 - 也不角落找寻其他的方式。

引述manual page of session_start,虽然:

在session_start()当启用 透明sid将注册内部 输出处理程序URL重写。如果用户使用ob_gzhandler或使用ob_start(), ,输出处理程序的顺序为 对于正确的输出很重要。对于 示例,用户必须在会话开始之前注册 ob_gzhandler。

但是,这是某种特殊的情况:事情是,在这里,该输出处理的顺序很重要:如果你想要一个处理程序修改事物的另一那样,他们在被执行“正确的顺序。


一般来说,如果你不使用那种处理的(Apache和mod_deflate做大量的工作,当谈到压缩输出,例如),唯一重要的事情是,头一定不能在您拨打电话session_start之前发送(因为根据您的配置,session_start发送的cookies作为HTTP标头传送)

和头作为任何数据立即发送具有发送 - 也就是说,只要有任何输出的<?php ?>标签外,甚至一个空白:

注意:如果你是使用基于cookie的 会话时,必须在输出到浏览器之前调用 session_start(),然后才能将任何内容输出到 。

ob_start表示PHP有缓冲数据:

该函数将变为输出缓冲 上。虽然输出缓冲 处于活动状态,但 脚本(标题除外)没有输出,而是 输出存储在内部 缓冲区中。

这样,在你居然说,你自己,“发送数据”输出不发送电子邮件。这意味着头不立即发送 - 这意味着session_start可以稍后调用,即使应该已经输出,如果ob_start尚未使用。


希望这可以让事情变得更加清晰...

如果默认你output_bufferingOff,你已经不幸数据的单字节发送回客户端,然后你HTTP头已经发送。这有效地防止了session_start()将cookie标头传递回客户端。通过调用ob_start()您启用缓冲并因此延迟发送http标头。

session_start如果设置了某些配置选项,可能需要修改HTTP标头。例如,其中一个是session.use_cookies,它需要设置/修改Set-Cookie标题字段。

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

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

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

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

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

一般来说,如果你不使用那种类型的处理程序(例如Apache和mod_deflate在压缩输出方面做得很好),唯一重要的是在调用之前不得发送标题session_start(因为根据您的配置,session_start发送的cookies作为HTTP标头传递)。

和头作为任何数据立即发送具有发送 - 也就是说,只要有任何输出的<?php ?>标签外,甚至一个空白:

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

ob_start表示PHP有缓冲数据:

该函数将变成输出缓冲上。当输出缓冲处于活动状态时,脚本中不会输出任何输出(标题除外),而是将输出存储在内部缓冲区中。

通过这种方式,在您真正说“发送数据”之前,不会发送输出。这意味着头文件不会立即发送 - 即,如果ob_start尚未使用,即使应该输出,也可以稍后调用session_start。

session_start();应在任何头文件发出之前调用。 ob_start()将压缩输出一段时间,你可以打破这个规则。通常情况下,ob_start()是一个快速修复,以防您正在调试未知的东西;下面的一切都按预期工作(不仅仅是书面的;-))。我更喜欢将ob_start()稍后用于session_start()。