我刚刚注意到一些奇怪的事情。我认为,正如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。