【问题标题】:session_start() works after output being sentsession_start() 在发送输出后工作
【发布时间】:2012-01-03 19:09:37
【问题描述】:

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

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

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

[2012 年 1 月 3 日星期二 11:57:21] [错误] [客户端 127.0.0.1] PHP 警告:session_start():无法发送会话缓存限制器 - 标头已在 /var/www/sessions/write.php 中发送在第 5 行 [2012 年 1 月 3 日星期二 11:57:21] [错误] [客户端 127.0.0.1] PHP 堆栈跟踪: [2012 年 1 月 3 日星期二 11:57:21] [错误] [客户端 127.0.0.1] PHP 1. {main}() /var/www/sessions/write.php:0 [2012 年 1 月 3 日星期二 11:57:21] [错误] [客户端 127.0.0.1] PHP 2. session_start() /var/www/sessions/write.php:5

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

【问题讨论】:

标签: php session


【解决方案1】:

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

确实如此。服务器端 cookie 设置(与 JavaScript cookie 设置不同)通过发送 HTTP 标头来工作。 HTTP 标头位于实际文档之前:一旦您开始发送文档,就没有更多的标头了。

在您的情况下,会发生这种情况:

echo 'foo';

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

output_buffering 指令可能是嫌疑犯。

【讨论】:

  • output_buffering 设置为 4096implicit_flush 设置为 Off。所以,为了让我的脚本在不必调用flush() 的情况下不再工作,我应该启用implicit_flush 并将output_buffering 设置为0,对吗?
【解决方案2】:

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

【讨论】:

  • 我做到了。我删除了PHPSESSID,然后再次运行脚本,同样的事情发生了:如果我在echos 之后添加flush()read.php 显示NULL ,如果我不这样做,它会按预期显示 baz
  • 您必须在 php 设置中启用输出缓冲
猜你喜欢
  • 2014-12-02
  • 1970-01-01
  • 1970-01-01
  • 2011-04-15
  • 1970-01-01
  • 1970-01-01
  • 2014-03-22
  • 2019-01-19
  • 1970-01-01
相关资源
最近更新 更多