Detaillierte Erläuterung der PHP-Serialisierungs- und Deserialisierungsprinzipien

jacklove
Freigeben: 2023-04-02 07:58:01
Original
1778 Leute haben es durchsucht

Dieser Artikel teilt Ihnen das relevante Wissen über PHP-Serialisierungs- und Deserialisierungsprinzipien in der PHP-Deserialisierungs-Schwachstellenreihe mit. Freunde, die dies benötigen, können darauf zurückgreifen.

0. Vorwort

Die Serialisierung von Objekten wird nicht im Detail beschrieben ähnlich wie json.

Wir müssen mehrere Probleme lösen, wenn wir die Serialisierung und Deserialisierung von Objekten in einer beliebigen Sprache entwerfen.

Nach der Serialisierung eines Objekts ist das Serialisierungsergebnis eine selbstbeschreibende Funktion (Kenntnis der spezifischen Typ dieses Objekts aus dem Serialisierungsergebnis

Die Kenntnis des Typs reicht nicht aus, Sie müssen natürlich auch den spezifischen Wert kennen, der diesem Typ entspricht).

Berechtigungskontrolle während der Serialisierung, Sie können Serialisierungsfelder usw. anpassen. Dies ist beispielsweise sehr praktisch in Golang.

Zeitleistungsprobleme: In einigen leistungsempfindlichen Szenarien ist die Objektserialisierung nicht möglich ein Hindernis sein, zum Beispiel: Hochleistungsdienste (ich verwende oft Protobuf für die Serialisierung). Probleme mit der Speicherplatzleistung: Das Ergebnis nach der Serialisierung darf nicht zu lang sein, z. B. ein int im Speicherobjekt. Nach der Serialisierung beträgt die Datenlänge das Zehnfache der Länge von int. Dann liegt ein Problem mit diesem Serialisierungsalgorithmus vor.

Dieser Artikel erläutert nur die Serialisierung und Deserialisierung in PHP aus der Perspektive des PHP-Codeprozesses . Denken Sie daran, dass Serialisierung und Deserialisierung nur für Objektdaten gelten.

1 >

PHP bietet im Gegensatz zu C++ nativ eine Objektserialisierungsfunktion...^_^ Es ist auch sehr einfach zu verwenden, nur zwei Schnittstellen.

class fobnn
{
 public $hack_id;
 private $hack_name;
 public function __construct($name,$id)
 {
  $this->hack_name = $name;
  $this->hack_id = $id;
 }
 public function print()
 {
  echo $this->hack_name.PHP_EOL;
 }
}
$obj = new fobnn('fobnn',1);
$obj->print();
$serializedstr = serialize($obj); //通过serialize接口序列化
echo $serializedstr.PHP_EOL;;
$toobj = unserialize($serializedstr);//通过unserialize反序列化
$toobj->print();
Nach dem Login kopieren

fobnn
O:5:"fobnn":2:{s:7:"hack_id";i:1;s:16:"fobnnhack_name";s:5:"fobnn";}
fobnn
Nach dem Login kopieren

Diese Zeichenfolge ist das Ergebnis der Serialisierung. Nach dem Lesen können Sie feststellen, dass sie über den Objektnamen abgebildet wird /Mitgliedsname. Natürlich sind die Labelnamen nach der Serialisierung von Mitgliedern mit unterschiedlichen Zugriffsrechten etwas anders.

Gemäß den drei oben genannten Fragen können wir einen Blick auf

<🎜 werfen >1. Selbstbeschreibende Funktion

O:5:"fobnn":2 wobei o den Objekttyp darstellt und der Typname fobnn ist. In diesem Format zeigt die 2 an, dass es zwei Mitglieder gibt

Bei den Mitgliedsobjekten handelt es sich tatsächlich um den gleichen Satz von Unterbeschreibungen. Die Funktion der

Selbstbeschreibung besteht hauptsächlich darin, das Objekt durch Zeichenfolgen aufzuzeichnen und die Namen der Mitglieder.

2. Leistungsprobleme

Die Zeitleistung der PHP-Serialisierung wird in diesem Artikel nicht analysiert, aber die Serialisierungsergebnisse sind denen tatsächlich ähnlich definiert durch json/bson Ein Protokoll hat einen Protokollheader, der den Typ beschreibt, und der Protokollhauptteil beschreibt den Wert, der dem Typ entspricht. Das Serialisierungsergebnis wird nicht komprimiert. Magie in der Deserialisierung Die Methode

entspricht dem zweiten oben genannten Problem. Tatsächlich gibt es auch Lösungen in PHP. Eine davon ist eine magische Methode und die zweite ist eine benutzerdefinierte Serialisierungsfunktion. Lassen Sie es uns zuerst vorstellen. Die magischen Methoden __sleep und __wakeup

class fobnn
{
 public $hack_id;
 private $hack_name;
 public function __construct($name,$id)
 {
  $this->hack_name = $name;
  $this->hack_id = $id;
 }
 public function print()
 {
  echo $this->hack_name.PHP_EOL;
 }
 public function __sleep()
 {
  return array("hack_name");
 }
 public function __wakeup()
 {
  $this->hack_name = &#39;haha&#39;;
 }
}
$obj = new fobnn(&#39;fobnn&#39;,1);
$obj->print();
$serializedstr = serialize($obj);
echo $serializedstr.PHP_EOL;;
$toobj = unserialize($serializedstr);
$toobj->print();
Nach dem Login kopieren

fobnn
O:5:"fobnn":1:{s:16:"fobnnhack_name";s:5:"fobnn";}
haha
Nach dem Login kopieren

rufen __sleep vor der Serialisierung auf und kehren zurück ist ein Array von Mitgliedsnamen, die serialisiert werden müssen. In dem Fall, dass ich nur hack_name zurückgegeben habe, ist im Ergebnis nur das Mitglied hack_name serialisiert.

in Nach Abschluss der Serialisierung können wir einige Folgearbeiten durchführen, z. B. die erneute Verbindung zur Datenbank.

3

interface Serializable {
abstract public string serialize ( void )
abstract public void unserialize ( string $serialized )
}
Nach dem Login kopieren

Über diese Schnittstelle können wir das Serialisierungs- und Deserialisierungsverhalten anpassen. Diese Funktion kann hauptsächlich zur Anpassung unseres Serialisierungsformats verwendet werden.

class fobnn implements Serializable
{
 public $hack_id;
 private $hack_name;
 public function __construct($name,$id)
 {
  $this->hack_name = $name;
  $this->hack_id = $id;
 }
 public function print()
 {
  echo $this->hack_name.PHP_EOL;
 }

 public function __sleep()
 {
  return array(&#39;hack_name&#39;);
 }

 public function __wakeup()
 {
  $this->hack_name = &#39;haha&#39;;
 }

 public function serialize()
 {
  return json_encode(array(&#39;id&#39; => $this->hack_id ,&#39;name&#39;=>$this->hack_name ));
 }

 public function unserialize($var)
 {
  $array = json_decode($var,true);
  $this->hack_name = $array[&#39;name&#39;];
  $this->hack_id = $array[&#39;id&#39;];
 }
}
$obj = new fobnn(&#39;fobnn&#39;,1);
$obj->print();
$serializedstr = serialize($obj);
echo $serializedstr.PHP_EOL;;
$toobj = unserialize($serializedstr);
$toobj->print();
Nach dem Login kopieren

fobnn
C:5:"fobnn":23:{{"id":1,"name":"fobnn"}}
fobnn
Nach dem Login kopieren

Wenn eine benutzerdefinierte Serialisierungsschnittstelle verwendet wird, ist unsere magische Methode nutzlos.

4.Dynamischer PHP-Typ und PHP-Deserialisierung

Da die oben erwähnte selbstbeschreibende Funktion den Objekttyp im Serialisierungsergebnis speichert und PHP eine dynamische Typsprache ist, dann wir kann ein einfaches Experiment durchführen.

class fobnn
{
 public $hack_id;
 public $hack_name;
 public function __construct($name,$id)
 {
  $this->hack_name = $name;
  $this->hack_id = $id;
 }
 public function print()
 {
  var_dump($this->hack_name);
 }
}
$obj = new fobnn(&#39;fobnn&#39;,1);
$obj->print();
$serializedstr = serialize($obj);
echo $serializedstr.PHP_EOL;;
$toobj = unserialize($serializedstr);
$toobj->print();
$toobj2 = unserialize("O:5:\"fobnn\":2:{s:7:\"hack_id\";i:1;s:9:\"hack_name\";i:12345;}");
$toobj2->print();
Nach dem Login kopieren

Wir ändern das Deserialisierungsergebnis von hack_name in den Typ int, i:12345

string(5) "fobnn"
O:5:"fobnn":2:{s:7:"hack_id";i:1;s:9:"hack_name";s:5:"fobnn";}
string(5) "fobnn"
int(12345)
Nach dem Login kopieren

Es kann festgestellt werden, dass das Objekt wieder erfolgreich serialisiert wurde! Natürlich bietet dieser Mechanismus von PHP eine flexible und veränderbare Syntax, birgt jedoch auch Sicherheitsrisiken um die Sicherheitsprobleme zu analysieren, die durch die Serialisierungs- und Deserialisierungsfunktionen von PHP verursacht werden.

Das oben Genannte ist das gesamte Wissen, das wir über die Prinzipien der PHP-Serialisierung und -Deserialisierung zusammengestellt haben.

Artikel, die Sie interessieren könnten:

Erläuterung des Code-Implementierungsprozesses für die WeChat-QR-Code-Anmeldefunktion basierend auf Swoole

Detaillierte Erläuterung der Implementierungsmethode von Hello Word in der PHP7-Erweiterungsentwicklung

Detaillierte Erläuterung der funktionsbasierten Methode zur Verwendung der lib-Bibliothek in PHP-Erweiterungsentwicklung


Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der PHP-Serialisierungs- und Deserialisierungsprinzipien. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage