PHP会话看起来损坏了



这用于从会话中获取先前服务的标记列表:

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)
  }
}

我说它是损坏的,因为当我手动制作一个类似的数组(这里的代码)时,输出在第三行中不显示& -它是array(3),而不是&array(3)。是什么导致了这种情况?


@Marc B暗示会话没有损坏。他的看法是,我们只有一个变量($_SESSION),包含对数组($marker)的引用,而不是数组本身;不是一个损坏的变量。嗯,会话对于会话使用目的来说是损坏的。两个迹象:

  1. 对同一脚本的第二次调用(我猜采取else路由)导致fatal error: Fatal error: Cannot use object of type DOMElement as array in ... on line 47。第47行是我们尝试向数组添加一个新的标记id的地方:$_SESSION['markers'][] = (int) $row['marker_id'];
  2. 当我试图反序列化会话文件的实际内容时,它失败了(代码在这里)。

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

引用自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'];
?>

加载页面,OK它显示42,重新加载页面…它显示43.

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

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

最新更新