シリアライズ
https://www.php.net/manual/ja/language.oop5.serialization.php
記憶装置等に、メモリ上のオブジェクト(インスタンス)等を記録しておきたい事があります。
このような時に、シリアライズをすることで「バイトストリームで表した文字列」に変換し、文字列として保存することが出来るようになります。
また「変換された、バイトストリームで表した文字列」を元のオブジェクト(インスタンス)等に戻すこともできます。これをアンシリアライズ(デシリアライズ)と言います。
シリアライズでは、「resource型および一部の object 以外」のすべての値を、保存可能な文字列に変換することができます。
シリアライズできない object については、PHPマニュアルに以下の記載があります。
https://www.php.net/manual/ja/function.serialize.php
PHP の組み込みオブジェクトの多くはシリアル化できないことに注意しましょう。しかし、 Serializable インターフェイスを実装しているか、あるいはマジックメソッド __serialize()/__unserialize() または __sleep()/__wakeup() を実装していればシリアル化することができます。 内部クラスがこれらの要件を満たしていない場合は、確実にシリアル化することはできません。 この規則には歴史的な例外もあり、 上記のインターフェイスやマジックメソッドを実装していない内部オブジェクトの中にも シリアル化可能なものがあります。
セキュリティ
https://www.php.net/manual/ja/function.unserialize.php
PHPマニュアルだと unserialize()
に記載があります。
ユーザ(外部)からの入力をアンシリアライズすると、「安全でないデシリアライゼーション(Insecure Deserialization)」「オブジェクトインジェクション(Object Injection)」と呼ばれる脆弱性につながります。
__sleep() と __wakeup()、__serialize()と__unserialize()
https://www.php.net/manual/ja/language.oop5.magic.php#object.sleep
https://www.php.net/manual/ja/language.oop5.magic.php#object.serialize
__sleep()
と __wakeup()
は、昔からあるマジックメソッドです。__sleep()
は「シリアライズ(保存)したいプロパティ名の配列を返す」ように作られます。「シリアライズ(保存)したくない」データがある時などに有効でしょう。__wakeup()
は「アンシリアライズ時の処理」を記載します。例えばオブジェクトの中にDBハンドルがあるような時に「アンシリアライズ時に、DB接続への再接続を行う」ような処理を書く事ができます。
__serialize()
と __unserialize()
は、PHP 7.4 以降で使えるマジックメソッドです。__serialize()
は「シリアライズ(保存)したいプロパティの、名前と値を連想配列にして返す」ように作られます。__unserialize()
は「引数で(恐らくは __serialize()
でreturnされたであろう)連想配列」を受け取ります。それを「自分のプロパティに入れる」処理を任意に書く事が出来ます。
__sleep()
と __serialize()
が共に存在する場合、__serialize()
が呼ばれます(__sleep()
は呼ばれません)。__wakeup()
と __unserialize()
が共に存在する場合、__unserialize()
が呼ばれます(__wakeup()
は呼ばれません)。
このコラムに関連するコードはこちらになります
https://github.com/php-engineer-examination/php8_column_expert/blob/main/src/030.php