Noté que las soluciones publicadas (en php.net) para decodificar manualmente las sesiones no son perfectas, así que contribuí con una solución más robusta.
La solución preg_match nunca puede funcionar. No es tan difícil encontrar un caso que pueda romper la deserialización. En el caso de Jason-joeymail es roturas en:
$_SESSION["test"] = ";oops|";
A continuación puede encontrar mi solución. No utiliza una expresión regular, sino la reversibilidad de la operación de serialización y la 'función' que serialize ignora toda entrada adicional cuando cree que está hecha. De ninguna manera es una solución hermosa o particularmente rápida, pero es una solución más robusta. He agregado un deserializador para "php" y "php_binary". Debería ser trivial agregar uno para "wddx".
class Session {
public static function unserialize($session_data) {
$method = ini_get("session.serialize_handler");
switch ($method) {
case "php":
return self::unserialize_php($session_data);
break;
case "php_binary":
return self::unserialize_phpbinary($session_data);
break;
default:
throw new Exception("Unsupported session.serialize_handler: " . $method . ". Supported: php, php_binary");
}
}
private static function unserialize_php($session_data) {
$return_data = array();
$offset = 0;
while ($offset < strlen($session_data)) {
if (!strstr(substr($session_data, $offset), "|")) {
throw new Exception("invalid data, remaining: " . substr($session_data, $offset));
}
$pos = strpos($session_data, "|", $offset);
$num = $pos - $offset;
$varname = substr($session_data, $offset, $num);
$offset += $num + 1;
$data = unserialize(substr($session_data, $offset));
$return_data[$varname] = $data;
$offset += strlen(serialize($data));
}
return $return_data;
}
private static function unserialize_phpbinary($session_data) {
$return_data = array();
$offset = 0;
while ($offset < strlen($session_data)) {
$num = ord($session_data[$offset]);
$offset += 1;
$varname = substr($session_data, $offset, $num);
$offset += $num;
$data = unserialize(substr($session_data, $offset));
$return_data[$varname] = $data;
$offset += strlen(serialize($data));
}
return $return_data;
}
}
Uso:
Session::unserialize(session_encode());
Utilicé la primera respuesta en esa página de manual. He editado mi publicación para incluir un enlace directo a esa respuesta. –
Noté que las soluciones publicadas php.net tienen un defecto grave. He contribuido con mi propia solución que evita el uso de una expresión regular. También lo publicaré aquí. – Halcyon