为什么 ob_start() 必须先于 session_start() 才能在 PHP 中工作?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1450990/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
why ob_start() must come ahead of session_start() to work in PHP?
提问by omg
I don't think it's reasonable.
我不认为这是合理的。
Why is it actually such a rule?
为什么它实际上是这样的规则?
回答by Pascal MARTIN
In the "normal case", I don't think ob_starthas to be called before session_start-- nor the other way arround.
在“正常情况”中,我认为不必ob_start在之前被调用session_start——反之亦然。
Quoting the manual page of session_start, though :
引用手册页session_start,虽然:
session_start() will register internal output handler for URL rewriting when trans-sid is enabled. If a user uses ob_gzhandler or like with ob_start(), the order of output handler is important for proper output. For example, user must register ob_gzhandler before session start.
session_start() 将在启用 trans-sid 时注册用于 URL 重写的内部输出处理程序。如果用户使用 ob_gzhandler 或类似的 ob_start(),输出处理程序的顺序对于正确输出很重要。例如,用户必须在会话开始前注册 ob_gzhandler。
But this is some kind of a special case : the thing is, here, that the order of output handlers is important : if you want one handler to modify things the other did, they have to be executed in the "right" order.
但这是某种特殊情况:这里的问题是,输出处理程序的顺序很重要:如果您希望一个处理程序修改另一个处理程序所做的事情,则它们必须以“正确”的顺序执行。
Generally, if you don't use that kind of handlers (Apache and mod_deflatedo a great job when it comes to compressing output, for instance), the only thing that matters is that headers must not be sent before you call session_start(because, depending on your configuration, session_startsends cookies, which are passed as HTTP headers).
通常,如果您不使用那种处理程序(例如,Apache 并且mod_deflate在压缩输出方面做得很好),唯一重要的是在您调用之前不得发送标头session_start(因为,取决于您的配置session_start发送 cookie,这些 cookie 作为 HTTP 标头传递)。
And headers are sent as soon as any piece of data has to be sent -- ie, as soon as there is any output, even one whitespace outside of <?php ?>tags :
一旦必须发送任何数据,就会发送标头 - 即,只要有任何输出,即使是<?php ?>标签之外的一个空格:
Note: If you are using cookie-based sessions, you must call session_start() before anything is outputted to the browser.
注意:如果您使用基于 cookie 的会话,则必须在向浏览器输出任何内容之前调用 session_start()。
ob_startindicates that PHP has to buffer data :
ob_start表示 PHP 必须缓冲数据:
This function will turn output buffering on. While output buffering is active no output is sent from the script (other than headers), instead the output is stored in an internal buffer.
此功能将打开输出缓冲。当输出缓冲处于活动状态时,脚本不会发送任何输出(标题除外),而是将输出存储在内部缓冲区中。
This way, output is not sent before you actually say, yourself, "send the data". This means headers are not send immediatly -- which means session_startcan be called later, even if there should have been output, if ob_starthad not been used.
这样,在您实际说“发送数据”之前,不会发送输出。这意味着头不会立即发送——这意味着session_start可以稍后调用,即使应该有输出,如果ob_start没有被使用。
Hope this makes things a bit more clear...
希望这能让事情更清楚一点......
回答by Michael Krelin - hacker
If by default your output_bufferingis Offand you have been unfortunate enough to send a single byte of data back to the client then your HTTPheaders have already been sent. Which effectively prevents session_start()from passing the cookie header back to the client. By calling ob_start()you enable buffering and therefore delay sending http headers.
如果默认情况下您output_buffering是,Off并且您不幸将单个字节的数据发送回客户端,那么您的HTTP标头已经发送。这有效地防止session_start()了将 cookie 标头传递回客户端。通过调用ob_start()您启用缓冲并因此延迟发送 http 标头。
回答by Gumbo
session_startmight want to modify the HTTP header if certain configuration options are set. One for example is session.use_cookiesthat requires to set/modify the Set-Cookieheader field.
session_start如果设置了某些配置选项,则可能需要修改 HTTP 标头。例如,session.use_cookies需要设置/修改Set-Cookie标头字段。
Modifying the HTTP header requires that there isn't any output that's already sent to the client as the HTTP header is sent right before the first output is sent.
修改 HTTP 标头要求没有任何已发送到客户端的输出,因为HTTP 标头是在发送第一个输出之前发送的。
So you either ensure that there is absolutely no output before the call of session_start. Or you use the output buffering controlto buffer the output so that the HTTP header can be modified even if there already is output.
因此,您要么确保在调用session_start. 或者您使用输出缓冲控制来缓冲输出,以便即使已经有输出也可以修改 HTTP 标头。
回答by Sarang Chaudhari
session_start()will register internal output handler for URL rewriting when trans-sidis enabled. If a user uses ob_gzhandleror like with ob_start(), the order of output handler is important for proper output.
session_start()将在trans-sid启用时注册用于 URL 重写的内部输出处理程序。如果用户使用ob_gzhandler或喜欢 with ob_start(),输出处理程序的顺序对于正确输出很重要。
For example, the user must register ob_gzhandlerbefore session start.
例如,用户必须ob_gzhandler在会话开始前注册。
But this is some kind of a special case. The thing is, here, that the order of output handlers is important. If you want one handler to modify things the other did, they have to be executed in the "right" order.
但这是某种特殊情况。这里的问题是,输出处理程序的顺序很重要。如果您希望一个处理程序修改另一个处理程序所做的事情,则必须以“正确”的顺序执行它们。
Generally, if you don't use that kind of handlers (Apache and mod_deflatedo a great job when it comes to compressing output, for instance), the only thing that matters is that headers must not be sent before you call session_start(because, depending on your configuration, session_startsends cookies, which are passed as HTTP headers).
通常,如果您不使用这种处理程序(例如,Apache 并且mod_deflate在压缩输出方面做得很好),唯一重要的是在您调用之前不得发送标头session_start(因为,取决于您的配置session_start发送 cookie,这些 cookie 作为 HTTP 标头传递)。
And headers are sent as soon as any piece of data has to be sent -- ie, as soon as there is any output, even one whitespace outside of <?php ?>tags :
一旦必须发送任何数据,就会发送标头 - 即,只要有任何输出,即使是<?php ?>标签之外的一个空格:
Note:If you are using cookie-based sessions, you must call session_start()before anything is outputted to the browser.
注意:如果您使用基于 cookie 的会话,则必须session_start()在向浏览器输出任何内容之前调用。
ob_startindicates that PHP has to buffer data :
ob_start表示 PHP 必须缓冲数据:
This function will turn output buffering on. While output buffering is active no output is sent from the script (other than headers), instead the output is stored in an internal buffer.
此功能将打开输出缓冲。当输出缓冲处于活动状态时,脚本不会发送任何输出(标题除外),而是将输出存储在内部缓冲区中。
This way, output is not sent before you actually say, yourself, "send the data". This means headers are not send immediatly -- which means session_start can be called later, even if there should have been output, if ob_starthad not been used.
这样,在您实际说“发送数据”之前,不会发送输出。这意味着头不会立即发送——这意味着 session_start 可以稍后调用,即使应该有输出,如果ob_start没有被使用。
回答by Bimal Poudel
session_start(); should be called before any headers are sent out. ob_start() will suppress the output for a while and you can break this rule. Usually ob_start() on the top is a quick fix in case you are debugging something unknown; everything below works as expected (not just as written ;-)). I prefer to use ob_start() later to session_start().
session_start(); 应该在发送任何标头之前调用。ob_start() 会暂时抑制输出,你可以打破这个规则。通常顶部的 ob_start() 是一个快速修复,以防您正在调试未知的东西;下面的一切都按预期工作(不仅仅是书面的;-))。我更喜欢在 session_start() 之后使用 ob_start()。

