はじめに
PHP Manual
PHP Manual»定義済みのインターフェイスとクラス»Serializable

Serializable インターフェイス

(PHP 5 >= 5.1.0, PHP 7, PHP 8)

独自のシリアライズ用のインターフェイスです。

このインターフェイスを実装したクラスは __sleep() や __wakeup() をサポートしなくなります。 シリアライズが必要な場合には、自動的に serialize() メソッドがコールされます。 このメソッドは __destruct() を実行しません。また、 メソッド内で明示的に書かない限りは一切の副作用を及ぼしません。 アンシリアライズされるときにはそのクラスが自動的に検知し、__construct() メソッドのかわりに適切な unserialize() メソッドがコンストラクタとしてコールされます。 必要であれば、unserialize() メソッドの中からコンストラクタをコールできます。

警告

PHP 8.1.0 以降は、 __serialize() と __unserialize() がない状態で Serializable を実装したクラスに対しては、推奨されない警告が発生します。

新しいコードでは、代わりに PHP 7.4.0 以降で利用可能な __serialize() と __unserialize() マジックメソッドを使いましょう。 クラスがこれらのマジックメソッドとこのインターフェイスの両方を宣言している場合、 serialize() は常に __serialize() を使い、 Serializable::serialize() がコールされることはありません。 一方、アンシリアライズでどちらが使われるかは、データの形式によって決まります。 PHP 7.4.0 以降が書き出したデータは __unserialize() が読み込み、 それより前のバージョンが書き出したデータは今でも Serializable::unserialize() が読み込みます。 そのため、Serializable の実装は、 このような古いデータを読み込む場合や、 Serializable による型宣言を満たす場合には、 依然として有用です。 4つのメソッドすべてを宣言すれば、あらゆるケースに対応でき、 推奨されない警告も発生しません。

注意:

マジックメソッドには専用のインターフェイスがありません。 そのため、Serializable を実装せずに マジックメソッドだけを宣言したクラスは、このインターフェイスのインスタンスにはなりません。 マジックメソッドを検出するには method_exists() を使います。

interface Serializable {
/* メソッド */
public function serialize(): ?string
public function unserialize(string $data): void
}

例1 PHP 7.1.0 から 7.3.0 までをサポートする

シリアライズ後の形式はマジックメソッドが受け持ち、インターフェイスのメソッドは そこに処理を委譲します。こうすることで、ひとつの表現で両方の仕組みをまかなえます。

<?php
class Task implements Serializable
{
    private $label;

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

    public function __serialize(): array
    {
        return ['label' => $this->label];
    }

    public function __unserialize(array $data): void
    {
        $this->label = $data['label'];
    }

    // PHP 7.4.0 以降はコールされません
    public function serialize()
    {
        return serialize($this->__serialize());
    }

    // PHP 7.4.0 以降も、それより前に書き出されたデータに対してはコールされます
    public function unserialize($data)
    {
        $this->__unserialize(unserialize($data));
    }
}

var_dump(serialize(new Task('deploy')));
?>

上の例の出力は以下となります。

string(40) "O:4:"Task":1:{s:5:"label";s:6:"deploy";}"

PHP 7.4.0 より前のバージョンでは、同じコードがインターフェイス経由でシリアライズを行い、 string(47) "C:4:"Task":31:{a:1:{s:5:"label";s:6:"deploy";}}" を出力します。

目次

To Top