session_start()在输出发送后有效

时间:2012-01-03 11:01:31

标签: php session

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

2 个答案:

答案 0 :(得分:7)

  

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

这是真的。服务器端的cookie设置(与JavaScript cookie设置不同)通过发送HTTP头来工作。 HTTP标头位于实际文档之前:一旦开始发送文档,就没有其他标题的位置了。

在你的情况下,会发生的是这一行:

echo 'foo';

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

output_buffering指令可能是嫌疑人。

答案 1 :(得分:0)

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