PHP会话看起来很糟糕

时间:2011-09-09 21:47:56

标签: php session

这用于从会话中获取以前提供的标记列表:

session_start();
if(!isset($_SESSION['markers'])) {
    $_SESSION['markers'] = array(0);
    $list = '0';
} else {
    $list = implode(', ', $_SESSION['markers']);
}

我使用$list来获取尚未投放的标记:

SELECT * FROM `markers` WHERE {other conditions} AND `marker_id` NOT IN($list) 

然后,对于返回的每一行,我将标记ID添加到会话:

while ($row = mysqli_fetch_assoc($result)){
  $_SESSION['markers'][] = (int) $row['marker_id'];
  ...
}

然而,在提供一些标记(比如说,8,36)后,会话看起来很糟糕。 var_dump($_SESSION);输出:

array(1) {
  ["markers"]=>
  &array(3) {
    [0]=>
    int(0)
    [1]=>
    int(8)
    [2]=>
    int(36)
  }
}

我说它已损坏,因为当我手动制作类似的数组(codepad here)时,输出在第三行中没有显示& - 它是array(3),而不是{{ 1}}。造成这种情况的原因是什么?

更新
@Marc B暗示会话没有损坏。他的看法是我们只有一个变量($ _SESSION),包含对数组的引用($ markers),而不是数组本身;和这不是一个腐败变量。好吧,会话 已损坏会话使用。两个迹象:

  1. 对同一个脚本的第二次调用(我猜测&array(3)路线)会产生elsefatal error。第47行是我们尝试向数组添加新标记ID的地方:Fatal error: Cannot use object of type DOMElement as array in ... on line 47
  2. 当我尝试反序列化会话文件的实际内容时,它失败了(codepad here)。

2 个答案:

答案 0 :(得分:3)

如果您将register_globals设置为On,则与$ _SESSION变量关联的全局变量是引用。资料来源:http://php.net/manual/en/reserved.variables.session.php

答案 1 :(得分:0)

从php手册中引用它 http://php.net/manual/en/reserved.variables.session.php

请注意,如果您将register_globals设置为On,则与$ _SESSION变量关联的全局变量是引用,因此这可能会导致一些奇怪的情况。

<?php

session_start();

$_SESSION['test'] = 42;
$test = 43;
echo $_SESSION['test'];

?>

加载页面,确定显示42,重新加载页面......显示43。

解决方案是在每次执行session_start()之后执行此操作:

<?php

if (ini_get('register_globals'))
{
    foreach ($_SESSION as $key=>$value)
    {
        if (isset($GLOBALS[$key]))
            unset($GLOBALS[$key]);
    }
}

?>