【问题标题】:In PHP, why are my session variables persisted as references?在 PHP 中,为什么我的会话变量作为引用保留?
【发布时间】:2011-01-22 01:09:22
【问题描述】:

这是代码。通过验证 IP 地址来检查会话 ID 是否被欺骗是一个简单的操作:

session_start();
$session_ip_address = $_SERVER['REMOTE_ADDR'];
if((!isset($_SESSION['SESSION_IP_ADDRESS'])) || !$_SESSION['SESSION_IP_ADDRESS']) {
    $_SESSION['SESSION_IP_ADDRESS'] = $session_ip_address;
}


if($_SESSION['SESSION_IP_ADDRESS'] != $_SERVER['REMOTE_ADDR']) {
    session_destroy();
    $_SESSION['security_error'] = true;
}

如果我在session_start() 之后插入var_dump($_SESSION) 并在脚本末尾再次插入,那么我第一次运行代码时(没有设置会话cookie)我首先看到数组是空的,然后它将我的 IP 地址分配给键“SESSION_IP_ADDRESS”。到目前为止,一切都很好。但是当我再次运行代码时,现在它显示“SESSION_IP_ADDRESS”在会话开始后立即存储为 reference(我可以通过字符串前面的 & 号来判断)。当我第三次运行它时,我看到 'SESSION_IP_ADDRESS' 现在是一个空引用 ('SESSION_IP_ADDRESS' => &null) 在会话开始后立即。怎么回事?!

重申一下,这是第一次的输出:

array(0) {
}
array(1) {
  ["SESSION_IP_ADDRESS"]=>
  string(11) "xx.xx.xxx.x"
} 

这是第二次的输出:

array(1) {
  ["SESSION_IP_ADDRESS"]=>
  &string(11) "xx.xx.xxx.x"
}
array(1) {
  ["SESSION_IP_ADDRESS"]=>
  &string(11) "xx.xx.xxx.x"
}

从那时起,第三次和每一次:

array(1) {
  ["SESSION_IP_ADDRESS"]=>
  &NULL
}
array(1) {
  ["SESSION_IP_ADDRESS"]=>
  &string(11) "xx.xx.xxx.x"
}

【问题讨论】:

    标签: php session pointers reference


    【解决方案1】:

    您的会话变量将被引用的唯一时间是当您将会话变量引用到另一个会话变量时(或者如果原始引用仍在范围内)。

    举例:

    session_start();
    $x = 'foo';
    $_SESSION['x'] = &$x;
    

    这会给你:

    array(1) {
      ["x"]=>
      string(3) "foo"
    }
    

    此时:

    $x = 'foo';
    $_SESSION['x'] = $x;
    $_SESSION['y'] = &$_SESSION['x']; // reference to another $_SESSION var
    

    或者这个:

    session_start();
    $x = 'foo';
    $_SESSION['x'] = $x;
    $_SESSION['y'] = &$x;
    var_dump($_SESSION); // reference still in scope
    

    会给你:

    array(2) {
      ["x"]=>
      string(3) "foo"
      ["y"]=>
      &string(3) "foo"
    }
    

    不管怎样,这样做:

    session_start();
    $y = $_SESSION['y'];
    $y = 'bar';
    

    不会修改y 会话变量。为此,您必须这样做:

    session_start();
    $y = &$_SESSION['y'];
    $y = 'bar';
    

    【讨论】:

      【解决方案2】:

      我的一个客户遇到了非常相似的问题。

      确保您的 PHP 配置 (PHP.ini) 具有 register_globals Off 否则常规变量会覆盖超全局变量包括 PHP 会话。

      【讨论】:

      • 我建议使用 phpinfo() 检查 register_globals 是否开启。因为它可能在php.ini中是关闭的,但是在代码中或者是通过.htaccess开启的
      【解决方案3】:

      它确实是按值赋值,$_SESSION 旁边的引用 & 与您的表达式 $_SESSION['x'] = $x; 无关

      【讨论】:

        【解决方案4】:

        如果我有:

        <?php
        
        $x = 'blah';
        $_SESSION['blah'] = $x;
        
        var_dump($_SESSION);
        

        我明白了:

        array(1) {
          ["blah"]=>
          string(4) "blah"
        }
        

        看不到参考资料。 Ubuntu 10.04.1 上的 PHP 5.3.2

        【讨论】:

        • 我认为你的意思是“在视线内”,我也一样。
        • 对。谢谢。固定...现在将其归咎于在漫长的一周之后的星期五。
        猜你喜欢
        • 1970-01-01
        • 2012-09-23
        • 1970-01-01
        • 1970-01-01
        • 2023-03-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-23
        相关资源
        最近更新 更多