这是代码。通过验证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;
}
如果我在var_dump($_SESSION)
之后插入session_start()
并再次在脚本末尾插入,那么我第一次运行代码(没有设置会话cookie)我首先看到数组为空,然后将我的IP地址分配给密钥'SESSION_IP_ADDRESS'。到现在为止还挺好。但是当我再次运行代码时,现在它显示会话开始后立即将'SESSION_IP_ADDRESS'存储为引用(我可以通过字符串前面的&符号来判断)。当我第三次运行它时,我发现会话开始后,'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"
}
答案 0 :(得分:2)
您的会话变量将成为引用的唯一时间是将会话变量引用到另一个会话变量(或者如果原始引用仍在范围内)。
每个例子:
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';
答案 1 :(得分:2)
我的一位客户遇到了类似的问题。
确保您的PHP配置(PHP.ini)具有register_globals Off
,否则常规变量会覆盖超级全局,包括 PHP会话。
答案 2 :(得分:0)
如果我有:
<?php
$x = 'blah';
$_SESSION['blah'] = $x;
var_dump($_SESSION);
我明白了:
array(1) {
["blah"]=>
string(4) "blah"
}
看不见任何参考文献。 Ubuntu 10.04.1上的PHP 5.3.2
答案 3 :(得分:0)
它确实按值分配,&
旁边的引用$_SESSION
与您的表达式$_SESSION['x'] = $x;