Ich bemerkte, dass die geposteten Lösungen (auf php.net) für die manuelle Dekodierung von Sitzungen nicht perfekt sind, also habe ich eine robustere Lösung beigesteuert.
Die preg_match-Lösung kann niemals funktionieren. Es ist nicht schwer, einen Fall zu finden, der die Deserialisierung durchbrechen könnte. Im Fall von jason-joeymail ist brechen auf:
$_SESSION["test"] = ";oops|";
Im Folgenden finden Sie meine Lösung zu finden. Es verwendet keinen regulären Ausdruck, sondern die Reversibilität der Serialisierungsoperation und das "Feature", das serialisiert alle weiteren Eingaben ignoriert, wenn es denkt, dass es fertig ist. Es ist keineswegs eine schöne oder besonders schnelle Lösung, aber es ist eine robustere Lösung. Ich habe einen Deserializer für "php" und "php_binary" hinzugefügt. Es sollte trivial sein, einen für "wddx" hinzuzufügen.
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;
}
}
Verbrauch:
Session::unserialize(session_encode());
Ich habe die erste Antwort auf dieser Handbuchseite verwendet. Ich habe meinen Beitrag bearbeitet, um einen direkten Link zu dieser Antwort hinzuzufügen. –
Mir ist aufgefallen, dass die geposteten Lösungen php.net einen gravierenden Makel haben. Ich habe meine eigene Lösung beigesteuert, die die Verwendung eines regulären Ausdrucks vermeidet. Ich werde es auch hier posten. – Halcyon