我刚注意到一些奇怪的事情。我认为,正如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 之后,会话也会被编写和阅读。
但是,如果我在flush()
之后添加对echo
的调用,Apache的错误日志会报告:
[2012年1月3日星期二11:57:21] [错误] [客户端127.0.0.1] PHP警告:session_start():无法发送会话缓存限制器 - 已在/var/www/sessions/write.php中发送的标头在第5行 [Tue Jan 03 11:57:21 2012] [错误] [client 127.0.0.1] PHP Stack trace: [Tue Jan 03 11:57:21 2012] [错误] [client 127.0.0.1] PHP 1. {main}()/var/www/sessions/write.php:0 [Tue Jan 03 11:57:21 2012] [错误] [client 127.0.0.1] PHP 2. session_start()/ var / www / session / edit.php:5
所以,我的问题是:为什么在echo
之后会话被正确写入?是不是立即发送到浏览器?并且,如果是这样,这是否意味着我可以在任何地方开始会话,只要我之前不打电话给flush()
?
答案 0 :(得分:7)
要使用基于cookie的会话,必须先调用session_start() 向浏览器输出任何内容。
这是真的。服务器端的cookie设置(与JavaScript cookie设置不同)通过发送HTTP头来工作。 HTTP标头位于实际文档之前:一旦开始发送文档,就没有其他标题的位置了。
在你的情况下,会发生的是这一行:
echo 'foo';
...实际上并没有将输出发送到浏览器。相反,它会将一些输出添加到稍后将发送的队列中。 PHP解释器配置为保存此输出,直到发生某些事件(可能是脚本结束或队列达到特定大小)。
output_buffering指令可能是嫌疑人。
答案 1 :(得分:0)
session_start()
中的此错误并不意味着您还没有任何打开的会话。此方法尝试创建新的会话ID,但您已经可以拥有一个。尝试在运行这些脚本之前删除所有cookie。