【问题标题】:Can multiple independent $_SESSIONs be used in a single PHP script?可以在单个 PHP 脚本中使用多个独立的 $_SESSION 吗?
【发布时间】:2010-06-30 14:44:41
【问题描述】:

我想在一个 PHP 脚本中使用两个独立的 $_SESSION。

我已尝试使用以下代码验证这是否可行。

error_reporting(-1);


session_name('session_one');
session_start();
$_SESSION = array();
$_SESSION['session_one_var'] = 'test_one';
$output1 =
(
   "session_id(): '" . session_id() . "'.<br/>\n" .
   "session_name(): '" . session_name() . "'.<br/>\n" .
   print_r($_SESSION, true)
);
session_write_close();
$_SESSION = array();


session_name('session_two');
session_start();
$_SESSION['session_two_var'] = 'test_two';
$output2 =
(
   "session_id(): '" . session_id() . "'.<br/>\n" .
   "session_name(): '" . session_name() . "'.<br/>\n" .
   print_r($_SESSION, true)
);
session_write_close();
$_SESSION = array();


echo "$output1<br/>\n<br/>\n$output2";

输出:

session_id(): 'f19aecd8d3ce0c5d444456d2387c6e35'.
session_name(): 'session_one'.
Array ( [session_one_var] => test_one )

session_id(): 'f19aecd8d3ce0c5d444456d2387c6e35'.
session_name(): 'session_two'.
Array ( [session_one_var] => test_one [session_two_var] => test_two ) 

我希望输出显示名为“session_one”的会话包含数组(“session_one_var”=>“test_one”),而名为“session_two”的会话包含数组(“session_two_var”=>“test_two”)。相反,“session_two”似乎与“session_one”是同一个会话。

如果我插入一行 'session_regenerate_id();'在第二个 'session_start();' 之后行,为“session_two”报告了不同的会话 id,但输出是相同的。见下文。

session_id(): 'f19aecd8d3ce0c5d444456d2387c6e35'.
session_name(): 'session_one'.
Array ( [session_one_var] => test_one )

session_id(): '3bcc74a7bcbac30e680c5b94fadcede1'.
session_name(): 'session_two'.
Array ( [session_one_var] => test_one [session_two_var] => test_two ) 

我做错了什么?

我知道以前在这个论坛上也有人问过类似的问题,herehere,但到目前为止提供的答案都未能启发我。

任何帮助将不胜感激。

【问题讨论】:

  • 发现这个:php.net/manual/en/function.session-start.php#91759 用数字键试试。然而,正如文档中所说:“访问您网站的访问者被分配了一个唯一的 ID,即所谓的会话 ID。这要么存储在用户端的 cookie 中,要么在 URL 中传播。”
  • 我要求一个会话独立于可能存在的任何其他会话,因为我正在尝试实现一个密码登录脚本以包含在任意页面的顶部。密码登录脚本将提示任何未登录的用户输入用户名和密码。在成功登录的情况下,用户先前提供了正确的用户名和密码的事实将存储在会话中。该脚本需要处理任意页面,因此它不会干扰访问受限页面可能使用的任何会话。
  • 使用现有会话的唯一问题是覆盖同名的会话变量。你可以在它们前面加上一些独特的东西,比如$_SESSION['__login_successful'] = true;

标签: php session


【解决方案1】:

会话 ID 在您运行第一个 session_start() 时从 cookie 中读取,即使您使用 session_write_close() 也会保留(否则您将无法调用 session_start() 重新打开同一会话)

我这里没有方便的 PHP 来测试这个,但理论上,您可以在第二个 session_start() 之前执行 session_id($_COOKIE['session_two']); 以切换到正确的 ID。

不过,我的 cookie 名称可能有误,所以您可能想printr($_COOKIE); 看看设置了哪些 cookie。

编辑:我忘了提及:会话的 cookie 名称基于 session_name,或者至少如果您只在文件中使用单个会话。

【讨论】:

  • 非常感谢。这解决了它,你对 cookie 名称的记忆也是正确的。
【解决方案2】:

根据docs

从 PHP 4.3.3 开始,在会话之前启动之后调用 session_start() 将导致 E_NOTICE 级别的错误。此外,第二个会话开始将被简单地忽略。

我的解释是不,无论名称如何,每个页面都不能多次使用 session_start()。

regenerate_id() 正在更改第一个会话的 ID,而第二个 session_start 被忽略。这就是您看到所描述的行为的原因。

我建议让我们知道您这样做的目的是什么,并且可能有人可以推荐另一种方法。

【讨论】:

  • 上述脚本未生​​成警告或错误,因为最初启动的会话已通过调用 session_write_close() 关闭。关闭最初启动的会话后,如果 session_write_close() 确实关闭了会话,则脚本应该处于与任何会话启动之前相同的状态。我还是一头雾水。
  • 嗯,实际上,我没有观察到您关闭了第一个。 cookie 问题听起来像是对这种行为的一个很好的解释。很高兴你解决了!
【解决方案3】:

我的解决办法是

ob_start();
$name1 = 'session_1';
session_name($name1);
if(empty($_COOKIE[$name1]))
    $sid = md5(microtime(true));
else
    $sid = $_COOKIE[$name1];
session_id($sid);
session_start();
$_SESSION['count']++;
print_r($_SESSION);
session_write_close();
$_SESSION = array();

$name2 = 'session_2';
session_name($name2);
if(empty($_COOKIE[$name2]))
    $sid2 = md5(microtime(true));
else
    $sid2 = $_COOKIE[$name2];
session_id($sid2);
session_start();
$_SESSION['count'] = $_SESSION['count'] + 2;
print_r($_SESSION);
session_write_close();
ob_end_flush();

【讨论】:

  • :请在您的回答中更具描述性。参考:How to Answer
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-31
  • 2010-10-25
  • 2017-03-17
  • 2019-04-21
  • 1970-01-01
相关资源
最近更新 更多