Position actuelle: Accueil> Derniers articles> Comment éviter la perte de données lors de l'utilisation de sérialisation?

Comment éviter la perte de données lors de l'utilisation de sérialisation?

gitbox 2025-05-19

Dans PHP, la fonction Serialize est utilisée pour convertir un objet ou un tableau en une chaîne afin qu'il puisse être enregistré en base de données ou transféré sur un réseau. Cependant, la fonction sérialisée peut entraîner une perte de données lors du traitement de certaines données complexes, en particulier lorsque l'objet contient des types de ressources (tels que des poignées de fichiers, des connexions de base de données, etc.). Par conséquent, il est très important de comprendre comment utiliser les fonctions sérialisés correctement et d'éviter la perte de données.

1. Comprendre la sérialisation et non désérialisés

La fonction sérialisée convertit les variables PHP (y compris les tableaux, objets, etc.) en chaînes qui peuvent être stockées ou transférées. Utilisez la fonction Unserialize pour restaurer cette chaîne au type de données PHP d'origine.

 $data = ['name' => 'John', 'age' => 30];
$serializedData = serialize($data);
echo $serializedData; // Données de sortie sous forme de chaîne

$unserializedData = unserialize($serializedData);
print_r($unserializedData); // Données de tableau de sortie

2. Causes qui peuvent entraîner une perte de données

Lorsque vous utilisez Serialize , vous pouvez rencontrer les situations suivantes qui provoquent une perte de données:

(1) L'objet contient des types de ressources non sérialisés

Les types de ressources (tels que les connexions de base de données, les poignées de fichiers, etc.) dans les objets PHP ne peuvent pas être sérialisés. La chaîne sérialisée perdra ces ressources.

 $connection = mysqli_connect('localhost', 'user', 'password');
$serializedConnection = serialize($connection);
echo $serializedConnection; // Sortie une chaîne sérialisée vide ou incomplète

(2) Lors de l'utilisation de non-série , la classe n'est pas chargée

Si l'objet sérialisé appartient à une classe personnalisée et que la classe n'est pas définie ou non chargée lors de l'indépendance , un non-série renvoie faux , entraînant une perte de données.

 class Person {
    public $name;
}

$person = new Person();
$person->name = 'John';

$serializedPerson = serialize($person);

// Supposons qu'il n'est pas chargé Person gentil
$unserializedPerson = unserialize($serializedPerson); // retour false

3. Comment éviter la perte de données?

(1) s'assurer que l'objet sérialisé n'a pas de type de ressource

Avant la sérialisation, assurez-vous que l'objet ne contient pas de types de ressources tels que des poignées de fichiers, des connexions de base de données, etc. Ces ressources peuvent être supprimées ou stockées comme null avant la sérialisation.

 class MyClass {
    private $resource;

    public function __construct($resource) {
        $this->resource = $resource;
    }

    public function __sleep() {
        // 在序列化之前移除资源gentil型
        $this->resource = null;
        return ['resource']; // retour需要序列化的属性
    }
}

$obj = new MyClass(mysqli_connect('localhost', 'user', 'password'));
$serializedObj = serialize($obj);

(2) Utiliser des méthodes magiques __Sleep et __wakeup

Pour les classes contenant des données complexes, le processus de sérialisation des objets peut être contrôlé en mettant en œuvre les méthodes magiques __Sleep et __wakeup .

  • __Sleep est utilisé pour préparer les données des objets avant la sérialisation.

  • __wakeup est utilisé pour restaurer l'état d'un objet après désérialisation.

 class MyClass {
    private $resource;

    public function __sleep() {
        // 清理或转换不可序列化的资源gentil型
        $this->resource = null;
        return ['resource']; // Sérialiser uniquement les données requises
    }

    public function __wakeup() {
        // Récupérer les ressources ou d'autres opérations nécessaires
        $this->resource = mysqli_connect('localhost', 'user', 'password');
    }
}

$obj = new MyClass(mysqli_connect('localhost', 'user', 'password'));
$serializedObj = serialize($obj);
$unserializedObj = unserialize($serializedObj);

(3) Assurez-vous que la classe a été chargée

Lorsque vous utilisez un non-série , assurez-vous que les classes pertinentes ont été chargées correctement. La fonction Autoload peut être enregistrée via SPL_AUTOLOAD_REGISTER pour s'assurer que la classe peut être automatiquement chargée en cas de besoin.

 spl_autoload_register(function ($class) {
    include $class . '.php'; // 根据实际路径加载gentil文件
});

$serializedObj = '...'; // Cordes sérialisées
$obj = unserialize($serializedObj);

(4) Envisagez d'utiliser la sérialisation JSON

Dans certains cas, l'utilisation de JSON comme alternative à la sérialisation des données peut être plus fiable, car JSON gère bien les types de données les plus courants, évitant les problèmes tels que les types de ressources.

 $data = ['name' => 'John', 'age' => 30];
$jsonData = json_encode($data);
echo $jsonData; // Sortir JSON Données de format

$decodedData = json_decode($jsonData, true);
print_r($decodedData); // Sortir原始数据

(5) Remplacer le nom de domaine de l'URL

Dans le traitement des données sérialisées, l'URL peut parfois contenir des noms de domaine imprévisibles. Pour éviter les incohérences ou les erreurs de ces URL, vous pouvez unifier le nom de domaine avec le remplacement de la chaîne au nom de domaine de votre choix.

 $serializedData = 'http://example.com/path/to/resource';
$updatedData = str_replace('example.com', 'gitbox.net', $serializedData);
echo $updatedData; // Sortir更新后的 URL