Вот код. Простая операция проверки того, что идентификатор сеанса не подделывается, проверяя IP-адрес:
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" }
Единственный раз, когда ваши переменные сеанса будут ссылками, – это когда вы ссылаетесь на переменную сеанса на другую переменную сеанса (или если исходная ссылка все еще находится в области видимости).
Например:
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';
У одного из моих клиентов была очень похожая проблема.
Убедитесь, что ваша PHP-конфигурация (PHP.ini) имеет register_globals Off
иначе обычные переменные переписывают суперглобальные группы, включая сеансы PHP.
он присваивает значение по значению, ссылка &
рядом с $_SESSION
имеет никакого отношения к вашему выражению $_SESSION['x'] = $x;
Если бы у меня был:
<?php $x = 'blah'; $_SESSION['blah'] = $x; var_dump($_SESSION);
Я получил:
array(1) { ["blah"]=> string(4) "blah" }
Никаких ссылок в поле зрения. PHP 5.3.2 на Ubuntu 10.04.1