我认为这是不合理的。
实际上,为什么会有这样的规定呢?
session_start
之前不需要调用ob_start
,反之亦然。session_start
的手册页面:
但这是某种特殊情况:问题在于输出处理程序的顺序很重要:如果您希望一个处理程序修改另一个处理程序所做的事情,则它们必须按“正确”的顺序执行。当启用trans-sid时,session_start()将为URL重写注册内部输出处理程序。如果用户使用ob_gzhandler或类似函数与ob_start()一起使用,则输出处理程序的顺序对于正确的输出很重要。例如,用户必须在会话开始之前注册ob_gzhandler。
mod_deflate
在压缩输出方面做得很好),那么唯一重要的事情是在调用session_start
之前不能发送标头(因为根据您的配置,session_start
会发送作为HTTP标头传递的cookie)。<?php ?>
标记外的一个空格,标头也会立即发送 - 即,只要有任何输出。output_buffering
是Off
,并且不幸地向客户端发送了一个字节的数据,则您的HTTP
标头已经被发送。这有效地防止了session_start()
将cookie标头传回客户端。通过调用ob_start()
,您可以启用缓冲,从而延迟发送http标头。在发送任何头文件之前,应该调用session_start()。ob_start()可以暂时抑制输出,您可以打破这个规则。通常情况下,在顶部使用ob_start()是一种快速修复方法,以防您正在调试某些未知内容;在此之下的所有内容都如预期工作(不仅仅是按照编写的方式处理);我更喜欢在session_start()之后再使用ob_start()。
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
。
session_start
可能会修改 HTTP 标头,如果设置了某些配置选项。例如,session.use_cookies 就需要设置/修改 Set-Cookie 标头字段。
修改 HTTP 标头要求在发送第一个输出之前没有向客户端发送任何输出,因为 HTTP 标头 是在第一个输出之前发送的。
因此,您可以确保在调用 session_start
之前没有任何输出。或者使用 输出缓冲控制 来缓冲输出,以便即使已经有输出,也可以修改 HTTP 标头。