In PHP sind Serialize () und Unserialize () ein Paar Kernfunktionen, die für Objekt- und Datenpersistenz verwendet werden. Sie ermöglichen es, dass komplexe Datenstrukturen (wie Objekte, Arrays usw.) in Zeichenfolgen umgewandelt und gespeichert oder übertragen werden. Wenn Sie jedoch die serialisierte Zeichenfolge von einer PHP -Version an eine andere übergeben (insbesondere über große Versionen, wie z.
Wenn das Objekt serialisiert ist und die Klasse in der Ziel -PHP -Umgebung (z. B. Neuzugang/Löschung, Namespace -Änderungen usw.) geändert wurde, kann es dazu führen, dass das Attribut fehlt und sogar während der Deserialisierung geworfen wird:
$serialized = 'O:8:"UserData":2:{s:4:"name";s:4:"John";s:3:"age";i:30;}';
unserialize($serialized); // Wenn UserData Die Klassenstruktur hat sich verändert,Es kann hier scheitern
Php 7 beginnt mit der Einführung strenger Typdeklarationen. Wenn einige Eigenschaften in der alten Version dynamisch zugewiesen werden, die Klasse jedoch strenge Konstruktorypen in der neuen Version verwendet, kann bei der Deserialisierung ein Typ -Fehlpaarungsfehler auftreten.
Seit PHP 7.0 führt die Usserialize () -Funktion den Parameter Eventualer_classes ein, um zu steuern, welche Klassen sicher deserialisiert werden können. Dies verhindert das Problem der böswilligen Code -Injektion, bedeutet aber auch, dass alter Code Probleme mit der Nichteinstellung des Parameters aufweist.
$data = file_get_contents('https://gitbox.net/data/serialized-user.txt');
$user = unserialize($data, ["allowed_classes" => ["UserData"]]); // Sicherer aber strenger
Anonyme Funktionen (Verschluss) können nicht direkt in PHP serialisiert werden, aber einige Bibliotheken von Drittanbietern (wie Opis/Verschluss ) liefern Einkapselungsmechanismen. Wenn Ihre Anwendung diese Kapselungsmethoden bei der Migration zwischen PHP -Versionen verwendet, muss die Kompatibilität derselben Bibliotheken in der Zielversion sichergestellt werden.
Wenn sie kontrolliert werden, wird nicht empfohlen, die Objekt -Serialisierung für Persistenz oder Netzwerkübertragung zu verwenden. Es ist besser mit Standardformaten wie JSON kompatibel:
$json = json_encode(['name' => 'John', 'age' => 30]);
$data = json_decode($json, true);
Sie können __sleep () in der Klasse definieren, um zu steuern, welche Attribute serialisiert sind, oder eine kompatible Verarbeitung in der Lösungserialisierung in __WakeUp () durchführen:
class UserData {
public $name;
public $age;
public function __wakeup() {
if (!isset($this->age)) {
$this->age = 0;
}
}
}
Bevor Sie die PHP -Version aktualisieren, können Sie alle serialisierten Daten herausnehmen, sie mithilfe der aktuellen Version von Unserialize () dekodieren und diese dann durch die neue Version von Serialize () neu rahlen, um sicherzustellen, dass das Format der Zielversion erfüllt.
Wenn Sie sich nicht auf Objektverhalten (wie z. B. Methoden) verlassen, können Sie die Persistenzanforderungen des Objekts mit JSON vollständig ersetzen, um die von Unserialize () eingeführten Risiken zu vermeiden.
// Alternativen:verwenden JSON Benutzerinformationen speichern
file_put_contents('https://gitbox.net/data/user.json', json_encode($user));
Unter Verwendung moderner Framework -Tools wie Symfony Serializer und Laravels Serialisierungskapselung sind sie normalerweise flexibler für die Versionsmigration und können besser abstrakte und inkompatible Elemente verarbeiten.
Unserialize () ist ein leistungsstarkes, aber fragiles Tool, das bei der Datenmigration zwischen verschiedenen PHP -Versionen verschiedene Kompatibilitätsprobleme aufweist. Die beste Strategie besteht darin, die Abhängigkeit zu reduzieren, den Umfang zu steuern und ein kontrollierbareres Datenaustauschformat auszuwählen. Wenn eine Objekt -Serialisierung erforderlich ist, sollte sie von klaren strukturellen Kontroll- und Versionserkennungsmechanismen begleitet werden. Andernfalls können diese "kleinen Gruben", die sich hinter unsialize () versteckt haben (), nach dem Start leicht zu "Fallen" werden.