В PHP почему мои переменные сеанса сохраняются в качестве ссылок?

Вот код. Простая операция проверки того, что идентификатор сеанса не подделывается, проверяя 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" } 

Solutions Collecting From Web of "В PHP почему мои переменные сеанса сохраняются в качестве ссылок?"

Единственный раз, когда ваши переменные сеанса будут ссылками, – это когда вы ссылаетесь на переменную сеанса на другую переменную сеанса (или если исходная ссылка все еще находится в области видимости).

Например:

 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