【PHP8.x】__serializeメソッドの使い方

__serializeメソッドの使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

__serializeメソッドは、DateTimeImmutableオブジェクトをシリアライズ(直列化)する際に自動的に呼び出されるメソッドです。PHPがオブジェクトを文字列として保存したり、ネットワークを通じて送信したりする際に、オブジェクトの状態をどのように表現するかを定義するために使用されます。このメソッドを実装することで、DateTimeImmutableオブジェクトのカスタムなシリアライズ処理を定義できます。

具体的には、__serializeメソッドは、オブジェクトの内部状態を表現する配列を返す必要があります。この配列は、PHPのserialize関数によって文字列に変換され、保存または送信されます。DateTimeImmutableクラスでは、通常、タイムスタンプやタイムゾーンなどの重要な情報を配列として返します。

オブジェクトがアンシリアライズ(直列化復元)される際には、__unserializeメソッドが呼び出され、__serializeメソッドが返した配列を元にオブジェクトの状態が復元されます。したがって、__serializeメソッドと__unserializeメソッドは対になって実装されることが一般的です。

DateTimeImmutableクラスで__serializeメソッドをオーバーライドする場合は、親クラス(DateTimeImmutable)の__serializeメソッドを呼び出す必要はありません。DateTimeImmutableクラス自体が内部状態を直接公開しないため、必要な情報を適切に配列として返すように実装します。これにより、DateTimeImmutableオブジェクトのシリアライズ処理を細かく制御し、データの整合性を保つことができます。システムエンジニアは、データベースへの保存やAPI通信など、オブジェクトを永続化または転送する必要がある場合に、このメソッドを活用してDateTimeImmutableオブジェクトの適切なシリアライズ処理を実装します。

構文(syntax)

1public DateTimeImmutable::__serialize(): array

引数(parameters)

引数なし

引数はありません

戻り値(return)

array

DateTimeImmutable オブジェクトの現在の状態をシリアライズ可能な形式で表す連想配列を返します。

サンプルコード

DateTimeImmutableの__serializeとserialize_precisionの影響を確認する

1<?php
2
3/**
4 * DateTimeImmutable::__serialize() のサンプルコード
5 * serialize_precision の設定による影響を確認する
6 */
7class DateTimeImmutableSerializer
8{
9    public function serializeDateTime(DateTimeImmutable $dateTime): string
10    {
11        return serialize($dateTime);
12    }
13
14    public function unserializeDateTime(string $serialized): DateTimeImmutable
15    {
16        return unserialize($serialized);
17    }
18}
19
20// serialize_precision のデフォルト値を使用
21ini_set('serialize_precision', -1); // デフォルト値
22
23$dateTime = new DateTimeImmutable('2024-01-01 10:20:30.123456');
24$serializer = new DateTimeImmutableSerializer();
25$serialized = $serializer->serializeDateTime($dateTime);
26$unserialized = $serializer->unserializeDateTime($serialized);
27
28echo "デフォルト serialize_precision:\n";
29echo "元のDateTime: " . $dateTime->format('Y-m-d H:i:s.u') . "\n";
30echo "シリアライズされた文字列: " . $serialized . "\n";
31echo "アンシリアライズされたDateTime: " . $unserialized->format('Y-m-d H:i:s.u') . "\n";
32
33// serialize_precision を変更
34ini_set('serialize_precision', 3);
35
36$dateTime = new DateTimeImmutable('2024-01-01 10:20:30.123456');
37$serialized = $serializer->serializeDateTime($dateTime);
38$unserialized = $serializer->unserializeDateTime($serialized);
39
40echo "\nserialize_precision = 3:\n";
41echo "元のDateTime: " . $dateTime->format('Y-m-d H:i:s.u') . "\n";
42echo "シリアライズされた文字列: " . $serialized . "\n";
43echo "アンシリアライズされたDateTime: " . $unserialized->format('Y-m-d H:i:s.u') . "\n";

DateTimeImmutable::__serialize() は、PHP 8 で DateTimeImmutable オブジェクトをシリアライズ(文字列に変換)する際に内部的に呼ばれるメソッドです。このメソッドは引数を取らず、シリアライズに必要なデータを含む配列を返します。

このサンプルコードでは、DateTimeImmutable オブジェクトのシリアライズとアンシリアライズ(文字列からオブジェクトへの復元)の過程で、serialize_precision という PHP の設定値がどのように影響するかを示しています。serialize_precision は、シリアライズされた浮動小数点数の精度を制御します。デフォルトでは -1 に設定されており、最大限の精度が保持されます。

コードでは、まず serialize_precision をデフォルト値の -1 に設定し、DateTimeImmutable オブジェクトをシリアライズ、アンシリアライズしています。次に、serialize_precision を 3 に変更し、同様の処理を行います。

出力結果を比較することで、serialize_precision の値によって、シリアライズされた文字列に含まれるマイクロ秒以下の精度が変化することを確認できます。serialize_precision を小さくすると、シリアライズされる際の精度が落ちるため、アンシリアライズ後の DateTimeImmutable オブジェクトのマイクロ秒以下の値が元の値と異なる場合があります。この設定は、データの保存や伝送において、精度とデータサイズのバランスを取る際に重要になります。

DateTimeImmutable::__serialize() はオブジェクトをシリアライズする際に内部的に呼ばれるメソッドです。このサンプルコードでは、特に serialize_precision の設定がシリアライズ結果に影響を与える点に注意が必要です。serialize_precision は浮動小数点数の精度を制御し、日時オブジェクトのマイクロ秒部分に影響します。デフォルトでは最大精度ですが、値を小さくすると精度が落ちます。シリアライズ/アンシリアライズ前後でマイクロ秒の値が変わる可能性があることを理解しておきましょう。ini_set() で設定値を変更する場合は、他の処理に影響を与えないよう、スコープを意識して使用してください。

PHP DateTimeImmutableの__serialize()でデータを保存する

1<?php
2
3/**
4 * DateTimeImmutable::__serialize() のサンプルコード
5 */
6class MyDateTime extends DateTimeImmutable
7{
8    private string $extraData;
9
10    public function __construct(string $datetime = "now", DateTimeZone $timezone = null, string $extraData = "")
11    {
12        parent::__construct($datetime, $timezone);
13        $this->extraData = $extraData;
14    }
15
16    public function getExtraData(): string
17    {
18        return $this->extraData;
19    }
20
21    public function __serialize(): array
22    {
23        // 親クラスのシリアライズ結果を取得
24        $parentData = parent::__serialize();
25
26        // 独自のデータを追加
27        $data = [
28            'parent' => $parentData,
29            'extraData' => $this->extraData,
30        ];
31
32        return $data;
33    }
34
35    public function __unserialize(array $data): void
36    {
37        // 独自のデータを復元
38        $this->extraData = $data['extraData'];
39
40        // 親クラスのアンシリアライズを実行
41        parent::__unserialize($data['parent']);
42    }
43}
44
45// オブジェクトの作成と初期化
46$dateTime = new MyDateTime('2024-01-01 10:00:00', new DateTimeZone('Asia/Tokyo'), 'Some extra info');
47
48// シリアライズ
49$serialized = serialize($dateTime);
50
51// アンシリアライズ
52$unserialized = unserialize($serialized);
53
54// 結果の確認
55echo "Original DateTime: " . $dateTime->format('Y-m-d H:i:s T') . " Extra data: " . $dateTime->getExtraData() . PHP_EOL;
56echo "Unserialized DateTime: " . $unserialized->format('Y-m-d H:i:s T') . " Extra data: " . $unserialized->getExtraData() . PHP_EOL;

このサンプルコードは、PHP 8のDateTimeImmutableクラスを拡張し、__serialize()メソッドと__unserialize()メソッドを実装することで、オブジェクトのシリアライズとアンシリアライズ処理をカスタマイズする方法を示しています。

DateTimeImmutableは日付と時刻を扱うための不変クラスですが、この例ではMyDateTimeクラスでextraDataという独自のプロパティを追加しています。__serialize()メソッドは、serialize()関数が呼ばれた際に、オブジェクトをシリアライズ(文字列に変換)するために実行されます。ここでは、親クラス(DateTimeImmutable)のシリアライズ結果と、追加したextraDataを配列にまとめて返しています。戻り値の配列は、シリアライズされた文字列に変換されます。引数は特にありません。

一方、__unserialize()メソッドは、unserialize()関数が呼ばれた際に、シリアライズされた文字列からオブジェクトを復元するために実行されます。ここでは、__serialize()で作成された配列を受け取り、extraDataプロパティを復元した後、親クラスのアンシリアライズ処理を呼び出しています。引数として、シリアライズされたデータから復元された配列を受け取ります。

この例では、MyDateTimeオブジェクトを作成し、シリアライズしてからアンシリアライズすることで、元のオブジェクトの状態が正しく保存され、復元されることを確認しています。この方法を使うことで、オブジェクトのシリアライズ/アンシリアライズ処理を細かく制御し、独自のデータを保存・復元できます。

DateTimeImmutableクラスを拡張してシリアライズをカスタマイズする例です。__serialize()メソッドは、オブジェクトをシリアライズする際に呼ばれ、配列を返します。この配列がserialize()関数によって文字列に変換されます。

注意点として、親クラスのシリアライズ結果(parent::__serialize())も必ず含める必要があります。独自のデータを追加するだけでなく、親クラスの状態も保存しないと、アンシリアライズ時に正しく復元できません。

__unserialize()メソッドは、unserialize()関数によってオブジェクトが復元される際に呼ばれます。ここでは、__serialize()で保存した独自のデータを復元し、parent::__unserialize()で親クラスのデータを復元しています。__serialize()__unserialize()は対で実装し、データの整合性を保つように注意しましょう。

【PHP8.x】__serializeメソッドの使い方 | いっしー@Webエンジニア