Dans PHP, Serialize () et Unserialize () sont une paire de fonctions centrales utilisées pour la persistance des objets et des données. Ils permettent de convertir les structures de données complexes (telles que les objets, les tableaux, etc.) en chaînes et stockées ou transférées. Cependant, lorsque vous passez la chaîne sérialisée d'une version PHP à une autre (en particulier sur les grandes versions, comme de PHP 5 à PHP 7 ou PHP 8), puis essayez de la désérialiser, vous pouvez rencontrer des problèmes inattendus.
Lorsque l'objet est sérialisé et que la classe a été modifiée dans l'environnement PHP cible (tel que l'addition / la suppression de l'attribut nouvel, les modifications de l'espace de noms, etc.), elle peut entraîner la manquante et même lancée l'attribut et même lancé pendant la désérialisation:
$serialized = 'O:8:"UserData":2:{s:4:"name";s:4:"John";s:3:"age";i:30;}';
unserialize($serialized); // si UserData La structure des classes a changé,Il peut échouer ici
PHP 7 commence à introduire des déclarations de type strict. Si certaines propriétés de l'ancienne version sont attribuées dynamiquement, mais que la classe utilise des types de constructeurs stricts dans la nouvelle version, une erreur de non-correspondance de type peut se produire lors de la désérialisation.
Depuis PHP 7.0, la fonction Unserialize () introduit le paramètre autorisé_classes pour contrôler quelles classes peuvent être désérialisées en toute sécurité. Cela empêche le problème de l'injection de code malveillant, mais signifie également que le vieux code peut avoir des problèmes de non-définition du paramètre.
$data = file_get_contents('https://gitbox.net/data/serialized-user.txt');
$user = unserialize($data, ["allowed_classes" => ["UserData"]]); // Plus sûr mais plus difficile
Les fonctions anonymes (fermeture) ne peuvent pas être sérialisées directement dans PHP, mais certaines bibliothèques tierces (telles que l'OPIS / fermeture ) fournissent des mécanismes d'encapsulation. Si votre application utilise ces méthodes d'encapsulation lors de la migration entre les versions PHP, il est nécessaire d'assurer la compatibilité des mêmes bibliothèques dans la version cible.
S'il est contrôlé, il n'est pas recommandé d'utiliser la sérialisation des objets pour la persistance ou la transmission du réseau. Il est plus compatible avec des formats standard tels que JSON:
$json = json_encode(['name' => 'John', 'age' => 30]);
$data = json_decode($json, true);
Vous pouvez définir __Sleep () dans la classe pour contrôler les attributs sérialisés ou effectuer un traitement compatible sur la sérialisation de la solution dans __wakeup () :
class UserData {
public $name;
public $age;
public function __wakeup() {
if (!isset($this->age)) {
$this->age = 0;
}
}
}
Avant de mettre à niveau la version PHP, vous pouvez éliminer toutes les données sérialisées, la décoder en utilisant la version actuelle d' Unserialize () , puis la respecter via la nouvelle version de Serialize () pour s'assurer que le format répond à la version cible.
Si vous ne comptez pas sur le comportement de l'objet (tel que les méthodes), vous pouvez complètement remplacer les exigences de persistance de l'objet par JSON pour éviter les risques apportés par Unserialize () .
// Alternatives:utiliser JSON Stocker les informations utilisateur
file_put_contents('https://gitbox.net/data/user.json', json_encode($user));
En utilisant des outils de framework modernes tels que Symfony Serializer et l'encapsulation de sérialisation de Laravel, ils sont généralement plus flexibles pour la migration des versions et peuvent mieux résumer et gérer les éléments incompatibles.
Unserialize () est un outil puissant mais fragile qui peut rencontrer divers problèmes de compatibilité lors de la migration des données entre différentes versions PHP. La meilleure stratégie consiste à réduire la dépendance, à contrôler la portée et à choisir un format d'échange de données plus contrôlable. Si la sérialisation des objets est requise, elle doit être accompagnée de mécanismes de contrôle structurel clair et de détection de version. Sinon, ces "petites fosses" cachées derrière Unserialize () peuvent facilement devenir des "pièges" après leur lancement.