Ho notato che le soluzioni pubblicate (su php.net) per le sessioni di decodifica manuale non sono perfette, quindi ho contribuito a una soluzione più solida.
La soluzione preg_match non può mai funzionare. Non è così difficile trovare un caso che potrebbe rompere la serializzazione. Nel caso di jason-joeymail è break su:
$_SESSION["test"] = ";oops|";
Qui di seguito potete trovare la mia soluzione. Non usa un'espressione regolare, ma piuttosto la reversibilità dell'operazione di serializzazione e la 'caratteristica' che serializza ignora tutti gli ulteriori input quando pensa di averlo fatto. Non è affatto una soluzione bella o particolarmente veloce, ma è una soluzione più robusta. Ho aggiunto un deserializzatore per "php" e "php_binary". Dovrebbe essere banale aggiungerne uno per "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;
}
}
Usage:
Session::unserialize(session_encode());
Ho usato la prima risposta su quella pagina di manuale. Ho modificato il mio post per includere un collegamento diretto a quella risposta. –
Ho notato che le soluzioni pubblicate su php.net hanno un grave difetto. Ho contribuito con la mia soluzione che evita l'uso di un'espressione regolare. Lo posterò anche qui. – Halcyon