En PHP, ¿por qué mis variables de sesión persisten como referencias?

Aquí está el código. Es una operación simple verificar que la identificación de la sesión no esté siendo falsificada al verificar la dirección 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; } 

Si inserto var_dump($_SESSION) justo después de session_start() y otra vez al final del script, la primera vez que ejecuto el código (sin un conjunto de cookies de sesión) veo que al principio el array está vacío, entonces tiene mi dirección IP asignada a la clave ‘SESSION_IP_ADDRESS’. Hasta aquí todo bien. Pero cuando ejecuto el código de nuevo, ahora muestra que ‘SESSION_IP_ADDRESS’ se almacena como referencia inmediatamente después de que se inicia la sesión (puedo decir por el signo y antes de la cadena). Cuando lo ejecuto por tercera vez, veo que ‘SESSION_IP_ADDRESS’ es ahora una referencia nula ( 'SESSION_IP_ADDRESS' => &null ) inmediatamente después de que se inicia la sesión. ¡¿Que esta pasando?!

Para reiterar, este es el resultado la primera vez:

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

Este es el resultado la segunda vez:

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

Y la tercera vez y cada vez a partir de entonces:

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

La única vez que sus variables de sesión serán referencias, es cuando hace referencia a una variable de sesión a otra variable de sesión (o si la referencia original aún está en el scope).

Por ejemplo:

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

Esto te dará:

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

Mientras esto:

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

O esto:

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

Te daría:

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

De cualquier manera, haciendo esto:

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

No modificará la variable de sesión y . Para hacer eso, tendrías que hacer:

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

Uno de mis clientes tuvo un problema muy similar.

Asegúrese de que su configuración de PHP (PHP.ini) tenga register_globals Off contrario, las variables regulares sobrescribirán superglobales, incluidas las sesiones de PHP.

asigna por valor, la referencia & junto a $_SESSION no tiene nada que ver con su expresión $_SESSION['x'] = $x;

Si tengo:

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

Yo obtengo:

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

Sin referencias a la vista. PHP 5.3.2 en Ubuntu 10.04.1