Session_start()在输出发送后工作


session_start() works after output being sent

我刚刚注意到一些奇怪的事情。我认为,正如PHP的手册所说,必须在将任何输出发送到浏览器之前调用session_start():

要使用基于cookie的会话,必须在向浏览器输出任何内容之前调用session_start()

因此,出于好奇,我创建了两个脚本。一个是write.php:

<?php
echo 'foo';
session_start();
$_SESSION['bar'] = 'baz';
?>

另一个是read。php:

<?php
echo 'foo';
session_start();
var_dump($_SESSION['bar']);
?>

令人惊讶的是,即使在echo foo之后,会话仍然被写入和读取。

但是,如果我在echo s之后添加对flush()的调用,Apache的错误日志报告:

[Tue Jan 03 11:57:21 2012] [error] [client 127.0.0.1] PHP警告:session_start(): Cannot send session cache limititer - headers已经在/var/www/session/write. PHP第5行发送了[Tue Jan 03 11:57:21 2012] [error] [client 127.0.0.1] PHP Stack trace:[Tue Jan 03 11:57:21 2012] [error] [client 127.0.0.1] PHP{主要}()/var/www/sessions/write.php: 0[Tue Jan 03 11:57:21 2012] [error] [client 127.0.0.1] PHPsession_start ()/var/www/sessions/write.php: 5

所以,我的问题是:为什么在echo之后会话写得正确?它不是立即发送到浏览器吗?而且,如果是这样,这是否意味着我可以在任何地方开始会话,只要我之前不调用flush() ?

要使用基于cookie的会话,必须先调用session_start()输出任何内容到浏览器。

这是真的。服务器端cookie设置(不像JavaScript cookie设置)通过发送HTTP报头来工作。HTTP报头在实际文档之前:一旦你开始发送文档,就没有地方再发送报头了。

在你的例子中,发生的是这一行:

echo 'foo';

…实际上不向浏览器发送输出。相反,它将一些输出添加到稍后将发送的队列中。PHP解释器被配置为保存此输出,直到某些事件发生(可能是脚本结束或队列达到一定大小)。

output_buffering指令可能是可疑的

session_start()中的这个错误并不意味着您还没有任何打开的会话。此方法尝试创建新的会话ID,但您可以已经有一个。在运行这些脚本之前,请尝试删除所有cookie。