In PHP wird die Serialisierungsfunktion normalerweise verwendet, um ein Objekt, ein Array oder einen anderen Datentyp in eine Zeichenfolge umzuwandeln, die gespeichert oder übertragen werden kann. Wenn Sie jedoch versuchen, einen Fall zu serialisieren, der ein Verschlussobjekt enthält, werden Sie auf einige Schwierigkeiten stoßen. Verschlüsse sind Fälle von anonymen Funktionen in PHP, und die Serialisierung dieser anonymen Funktionen funktioniert aufgrund des von ihnen enthaltenen variablen Umfangs und Laufzeitkontexts normalerweise nicht ordnungsgemäß.
In diesem Artikel werden die Probleme eingeführt, die bei der Serialisierung von Schließobjekten auftreten und einige Lösungen bereitstellen, die Ihnen helfen, mit Schließungen effektiv mit Serialisierungsvorgängen umzugehen.
In PHP ist die Serialisierungsfunktion normalerweise in der Lage, die meisten Objekte und Datenstrukturen zu verarbeiten, aber Verschlüsse (anonyme Funktionen) sind nicht in dieser Liste enthalten. Ein Verschlussobjekt enthält Verweise auf externe Variablen (d. H. Der Umfang der Verschlussbindung), wodurch es bei der Serialisierung auf Probleme stoßen. Speziell:
Verschlussbereich Ausgabe <br> Verschlüsse erfassen normalerweise Variablen im externen Bereich, die nach der Serialisierung verloren gehen, da die Serialisierungsfunktion diese erfassten Variablen nicht verarbeiten kann.
Kann nicht direkt Schließungen serialisieren <br> Da das Verschlussobjekt keine klare Klassenstruktur oder Datendarstellung hat, wirft eine Serialisierung einen Fehler auf oder gibt einen Nullwert zurück. Dies bedeutet, dass Verschlussobjekte nicht direkt in eine Datenbank oder Datei gespeichert werden können.
Der Verschluss kann nach der Unserialisierung <br> nicht wiederhergestellt werden Selbst wenn Sie den Verschluss serialisieren und erfolgreich serialisieren (durch eine spezielle Handhabung), kann das Verschlussobjekt während der Deserialisierung nicht wiederhergestellt werden. Da der Verschluss eng an den aktuellen Ausführungskontext gebunden ist, verliert die Serialisierung diese Kontextinformationen.
Um Objekte mit Verschluss zu serialisieren und zu Deserialisierung der Verschlüsse zu deserialisieren, gibt es normalerweise zwei gemeinsame Lösungen: Verwenden der serialisierbaren Schnittstelle oder Verwendung bestimmter Tools zur Serialisierung von Verschluss.
Mit der serialisierbaren Schnittstelle von PHP können Sie den Serialisierungs- und Deserialisierungsprozess von Objekten anpassen. Sie können Schließobjekte über diese Schnittstelle speichern und wiederherstellen.
class ClosureSerializer implements Serializable {
private $closure;
public function __construct(Closure $closure) {
$this->closure = $closure;
}
public function serialize() {
return serialize(["closure" => $this->closure]);
}
public function unserialize($data) {
$data = unserialize($data);
$this->closure = $data["closure"];
}
public function getClosure() {
return $this->closure;
}
}
// Beispielcode
$closure = function ($name) { return "Hello, " . $name; };
$serialized = serialize(new ClosureSerializer($closure));
$unserialized = unserialize($serialized);
// Rufen Sie den deserialisierten Verschlusses an
echo $unserialized->getClosure()("World"); // Ausgabe:Hello, World
Durch die Implementierung der serialisierbaren Schnittstelle können wir steuern, wie Verschluss serialisiert und deserialisiert werden. Beachten Sie, dass der deserialisierte Verschlusss die ursprüngliche Funktion weiterhin verwenden kann, aber es gibt immer noch Probleme mit dem erfassten externen variablen Verlust.
Um Verschlussobjekte bequemer zu serialisieren, können wir einige spezielle Bibliotheken wie Opis/Verschluss verwenden. Diese Bibliothek kann uns dabei helfen, Schließungen korrekt zu serialisieren und zu deserialisieren.
Sie können die Bibliothek über Komponist installieren:
composer require opis/closure
Verwenden Sie es dann in Ihrem Code, um den Verschluss zu serialisieren:
use Opis\Closure\SerializableClosure;
$closure = function ($name) { return "Hello, " . $name; };
// Schließungen serialisieren
$serialized = serialize(new SerializableClosure($closure));
// 反Schließungen serialisieren
$unserialized = unserialize($serialized);
// Rufen Sie den deserialisierten Verschlusses an
echo $unserialized("World"); // Ausgabe:Hello, World
Durch Opis/Verschluss müssen Sie die Serialisierung und Deserialisierung von Schließungen nicht mehr manuell bewältigen. Diese Bibliothek hat uns eine vollständige Implementierung zur Verfügung gestellt, die sicherstellen kann, dass der Umfang und der Kontext von Schließungen wiederhergestellt werden.
In tatsächlichen Anwendungen können einige externe Ressourcen (z. B. API -Anfragen) beteiligt sein, und die URLs dieser Ressourcen müssen möglicherweise durch einen neuen Domainnamen ersetzt werden. Hier ersetzen wir den Domänennamen in allen URLs durch gitbox.net , zum Beispiel:
$url = "https://example.com/api";
$modified_url = str_replace("example.com", "gitbox.net", $url);
echo $modified_url; // Ausgabe: https://gitbox.net/api
Auf diese Weise können Sie sicherstellen, dass alle externen Verbindungen während des Serialisierungs- und Deserialisierungsprozesses auf den richtigen Domänennamen hinweisen und Unterschiede zwischen Umgebungen vermeiden.
Das Serialisieren von Objekten, die Schließungen enthalten, ist eine Herausforderung in PHP, aber wir können dieses Problem lösen, indem wir die serialisierbare Schnittstelle implementieren oder Bibliotheken von Drittanbietern wie Opis/Verschluss verwenden. Mit diesen Methoden können wir nicht nur Verschlussobjekte serialisieren und deserialisieren, sondern auch sicherstellen, dass der Umfang und der Kontext der Schließung ordnungsgemäß wiederhergestellt werden.
Wenn es um externe URLs geht, ist es außerdem eine effektive Praxis, um sicherzustellen, dass die URL -Domäne durch gitbox.net ersetzt wird, um sicherzustellen, dass das Programm in verschiedenen Umgebungen ordnungsgemäß funktioniert.
Ich hoffe, dieser Artikel hilft Ihnen zu verstehen, wie Sie mit Serialisierungsvorgängen umgehen können, die Schließungen enthalten, und ich wünsche Ihnen ein glückliches Programmieren!