阻止php session_start()发送cookie

时间:2011-12-27 11:06:55

标签: php session header

我想知道在调用session_start()时是否有办法防止PHP发送cookie。

我的用例是网站优化:

  • (1a)我首先打开一个会话/发送标题。
  • (1b)然后生成并输出一些文本内容。
  • (1c)为了增强会话读/写,我不再需要在会话中写入时调用“session_write_close”。
  • (2)最后,我有一个页面后渲染过程(对于统计数据),需要对会话进行写访问。会话已关闭,我无法再次调用session_start(),因为它发送了一个cookie,而且为时已晚。这是一个计算量很大的过程,因此我必须在将页面发送到客户端后执行此操作。

客户端已收到会话cookie。所以我不需要session_start()发送新的(和冗余的)。

有人知道拦截cookie或类似方法的方法吗?当然我想避免“无法发送会话cookie - 已经发送的标题”。此错误对于用户是不可见的,因为该页面已经渲染,但在日志中看起来很难看。

我的问题似乎是多余的,但事实并非如此。我知道标题和内容是如何工作的(首先发送标题,然后发送内容)。只是PHP不让我做我想做的事。

3 个答案:

答案 0 :(得分:11)

  

我想知道在调用session_start()时是否有办法防止PHP发送cookie。

是的,告诉PHP不要使用cookie进行会话。 PHP设置为session.use_cookies

ini_set('session.use_cookies', 0); # disable session cookies
session_start();

默认启用Cookie是因为它们被认为比使用网址参数更安全(参见Sessions and security­Docs)。

  

(2)最后,我有一个页面后渲染过程(对于统计数据),需要对会话进行写访问。会话已关闭,我无法再次调用session_start(),因为它发送了一个cookie,而且为时已晚。这是一个计算繁重的过程,因此我必须在将页面发送到客户端之后执行此操作。

通过将cookie添加到$_COOKIE superglobal array­Docs中,可能会告诉PHP已经设置了cookie。我从来没有试过它,但是如果你使用session_start()并且PHP看到会话cookie已经设置(由浏览器而不是PHP,$_COOKIE代表浏览器cookie),它不会发送标题(再次)设置cookie(据我所知你是你想要的)。


编辑:可以使用的一些测试脚本:

<?php
header('Content-Type: text/plain;');

echo "Incomming Cookies:\n";
print_r($_COOKIE);

// to simulate that this is a new session, the session cookie is removed
// which makes PHP think it is a new session when invoking session_start()
// unset($_COOKIE['PHPSESSID']);

// run the first session
session_start(); // creates the session cookie (as we don't have one yet)
printf("Session %s has been started: %s\n", session_name(), session_id());
var_dump($_SESSION);
$_SESSION['variable'] = isset($_SESSION['variable']) ? $_SESSION['variable']++ : 0;
session_commit();

printf("Session has been closed, remaining id is: %s\n", session_id());

// visual confirmation that session cookie has been created
echo "Outgoing Cookies:\n";
print_r(headers_list());

// run the second session
ini_set('session.use_cookies', 0); # disable session cookies
session_start();
printf("Second session %s has been started: %s\n", session_name(), session_id());
var_dump($_SESSION);
$_SESSION['2nd-variable'] = isset($_SESSION['2nd-variable']) ? $_SESSION['2nd-variable']++ : 0;
session_commit();

您需要使用Web浏览器调用它(并且必须配置PHP会话才能工作)。

答案 1 :(得分:5)

我想我应该提一下防止在调用session_start时发送cookie(和缓存限制器)标头的另一种好方法。

session_start调用采用options数组,您可以在其中设置任何会话。前缀变量,你可以为这个调用禁用这些东西。

session_start(array(
   'use_cookies' => '0',
   'cache_limiter' => ''
));

请注意,use_cookies会阻止发送cookie,并且将缓存限制器设置为空字符串会使其无法更新缓存标头(不是最佳记录功能)。

以下是两个会解决的问题(当您需要完成多个会话时,这很有用)。

Warning: session_start(): Cannot send session cookie - headers already sent

Warning: session_start(): Cannot send session cache limiter - headers already sent

答案 2 :(得分:-3)

您可以使用ob_start()函数来缓冲标题/内容,您可以使用ob_clean()清除缓冲区内容