Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【PHP8.x】SplDoublyLinkedList::unserialize()メソッドの使い方

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

作成日: 更新日:

基本的な使い方

unserializeメソッドは、PHPのSplDoublyLinkedListクラスに属し、シリアライズされた文字列データからオブジェクトの状態を復元する処理を実行するメソッドです。このメソッドは、PHPの組み込み関数であるunserialize()が呼び出された際に、その引数として渡されたシリアライズデータをもとに、SplDoublyLinkedListオブジェクトが自身を再構築するために内部的に利用されます。

具体的には、serialize()関数によって文字列形式に変換されたSplDoublyLinkedListオブジェクトの要素や内部状態を、このunserializeメソッドが解析し、新しいSplDoublyLinkedListオブジェクトとして元の状態に復元します。これにより、アプリケーションは、一度ファイルやデータベースなどに保存されたリストデータを読み込み、再び操作可能なSplDoublyLinkedListオブジェクトとして利用することが可能になります。

システムエンジニアを目指す初心者の方にとっては、オブジェクトの永続化と復元の仕組みを理解する上で重要な要素の一つですが、通常、このunserializeメソッドを開発者が直接コード内で呼び出すことはありません。PHPのunserialize()関数が自動的に呼び出す内部的な挙動として理解していただくことが大切です。

PHP 8のバージョンでは、ユーザー定義クラスでシリアライズ・デシリアライズ処理をカスタマイズする場合、Serializableインターフェースに定義されているunserializeメソッドではなく、__unserialize()マジックメソッドの使用が推奨されています。しかし、SplDoublyLinkedListのようなPHPに組み込まれたクラスでは、引き続きこのunserializeメソッドがオブジェクトの復元処理に内部的に利用されます。

構文(syntax)

1<?php
2
3(new SplDoublyLinkedList())->unserialize('O:20:"SplDoublyLinkedList":0:{}');

引数(parameters)

string $data

  • string $data: SplDoublyLinkedList オブジェクトを unserialize するための文字列データ

戻り値(return)

戻り値なし

戻り値はありません

サンプルコード

SplDoublyLinkedList::unserialize エラーハンドリング

1<?php
2
3/**
4 * SplDoublyLinkedList::unserialize の使用例とエラーハンドリング。
5 *
6 * SplDoublyLinkedList::unserialize メソッドは、不正なシリアライズ文字列が
7 * 与えられた場合に PHP Warning を発生させます。
8 * この関数は、その Warning を捕捉し、ErrorException として処理する方法を
9 * システムエンジニアを目指す初心者にも理解しやすいように示します。
10 *
11 * キーワード: php unserialize エラー
12 */
13function demonstrateSplDoublyLinkedListUnserializeErrorHandling(): void
14{
15    // PHP Warning を ErrorException に変換するカスタムエラーハンドラーを設定します。
16    // これにより、通常 Warning で停止しない処理を try-catch で捕捉できるようになります。
17    $previousErrorHandler = set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) {
18        if ($errno === E_WARNING) {
19            // E_WARNING の場合に ErrorException をスローします。
20            throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
21        }
22        // その他のエラータイプは、PHP のデフォルトエラーハンドラーに処理を任せます。
23        return false;
24    });
25
26    try {
27        echo "--- 正常な SplDoublyLinkedList::unserialize の例 ---\n";
28        $originalList = new SplDoublyLinkedList();
29        $originalList->push('要素A');
30        $originalList->unshift('要素B');
31        $originalList->add(1, '要素C'); // インデックス1に要素を追加
32
33        echo "元のリストの内容:\n";
34        foreach ($originalList as $index => $value) {
35            echo "  [{$index}]: {$value}\n";
36        }
37
38        // SplDoublyLinkedList をシリアライズします。
39        // このデータは unserialize で元の状態に戻せます。
40        $serializedData = serialize($originalList);
41        echo "シリアライズされたデータ: " . $serializedData . "\n";
42
43        // 新しい SplDoublyLinkedList インスタンスを作成し、データを復元します。
44        $restoredList = new SplDoublyLinkedList();
45        $restoredList->unserialize($serializedData);
46
47        echo "正常に復元されたリストの内容:\n";
48        foreach ($restoredList as $index => $value) {
49            echo "  [{$index}]: {$value}\n";
50        }
51        echo "\n";
52
53        echo "--- 不正な SplDoublyLinkedList::unserialize の例 (エラーハンドリングあり) ---\n";
54        // これは SplDoublyLinkedList の有効なシリアライズデータではありません。
55        // stdClass オブジェクトのシリアライズデータや、無効な形式の文字列です。
56        $invalidSerializedData = 'O:8:"stdClass":0:{}'; // stdClass オブジェクトのシリアライズデータ
57
58        echo "不正なシリアライズデータ: " . $invalidSerializedData . "\n";
59        $errorList = new SplDoublyLinkedList();
60        // ここで Warning が発生し、カスタムエラーハンドラーによって ErrorException に変換されます。
61        $errorList->unserialize($invalidSerializedData);
62        echo "この行は実行されません (上記で例外がスローされるため)。\n";
63
64    } catch (ErrorException $e) {
65        // ErrorException を捕捉し、エラーメッセージを表示します。
66        echo "エラーを捕捉しました:\n";
67        echo "  メッセージ: " . $e->getMessage() . "\n";
68        echo "  ファイル: " . $e->getFile() . "\n";
69        echo "  行: " . $e->getLine() . "\n";
70        // 実際のシステムでは、ここでエラーログの記録や、ユーザーへの通知などの適切な処理を行います。
71    } finally {
72        // 処理の終了時に、設定したカスタムエラーハンドラーを元の状態に戻します。
73        // これにより、この関数の外での Warning は再び PHP のデフォルト動作に戻ります。
74        restore_error_handler();
75    }
76    echo "\n--- エラーハンドリングデモ終了 ---\n";
77}
78
79// サンプルコードを実行します。
80demonstrateSplDoublyLinkedListUnserializeErrorHandling();

SplDoublyLinkedList::unserialize メソッドは、PHPのSplDoublyLinkedListオブジェクトを、シリアライズ(直列化)された文字列から元の状態に復元するために使用されます。引数である $data には、事前に serialize() 関数などで生成された、リストの内容を表す文字列を渡します。このメソッドは、呼び出し元のリストインスタンス自身にデータを上書きするため、特定の戻り値はありません。

もし引数に、有効なSplDoublyLinkedListのシリアライズデータではない不正な文字列が渡された場合、PHPはWarning(警告)を発生させます。システムエンジニアにとって重要なのは、このような警告も適切に処理し、プログラムが予期せぬ動作をしないようにすることです。このサンプルコードでは、set_error_handler 関数を使ってPHPのWarningをErrorExceptionという例外に変換し、それを try-catch ブロックで捕捉する方法を示しています。これにより、通常はプログラムの実行を止めないWarningも、例外として扱い、エラーメッセージの表示やログ記録といった安全な処理を行うことができます。処理の終了時には、restore_error_handler でエラーハンドラーを元の状態に戻し、他の部分への影響を防いでいます。

SplDoublyLinkedList::unserializeメソッドは、不正なシリアライズ文字列を受け取るとPHP Warningを発生させます。このWarningはデフォルトではプログラムの実行を止めないため、サンプルコードのようにset_error_handlerErrorExceptionに変換し、try-catchで捕捉するエラーハンドリングが非常に重要です。特に、外部からの信頼できない入力を直接unserializeに渡すことは、セキュリティ上の重大な脆弱性(任意のコード実行など)につながる可能性があるため、絶対に行わないでください。set_error_handlerを設定した場合は、処理の最後に必ずrestore_error_handlerで元のエラーハンドラーに戻すことを忘れないでください。このメソッドは戻り値がなく、対象オブジェクトの状態を直接変更します。

PHP SplDoublyLinkedList::unserialize でリストをJSONに変換する

1<?php
2
3/**
4 * SplDoublyLinkedList::unserialize メソッドの使用例と、
5 * 復元したデータを JSON 形式に変換するサンプルコード。
6 *
7 * このコードは、SplDoublyLinkedList オブジェクトをシリアライズし、
8 * そのデータを unserialize メソッドで復元した後、
9 * 復元されたリストの内容を JSON 形式で出力します。
10 */
11
12// 1. 元になる SplDoublyLinkedList オブジェクトを作成し、データを追加します。
13$originalList = new SplDoublyLinkedList();
14$originalList->push('Apple');
15$originalList->push('Banana');
16$originalList->push('Cherry');
17$originalList->push(['id' => 101, 'name' => 'Orange']); // 複合型データも追加可能
18
19echo "--- 元のリストの内容 ---" . PHP_EOL;
20// リストの内容を一つずつ出力して確認
21foreach ($originalList as $item) {
22    echo (is_array($item) ? json_encode($item) : $item) . PHP_EOL;
23}
24echo PHP_EOL;
25
26// 2. SplDoublyLinkedList オブジェクト全体をシリアライズして文字列にします。
27// serialize() 関数は、PHP の値をバイトストリーム形式の文字列に変換します。
28$serializedData = serialize($originalList);
29echo "--- シリアライズされたデータ ---" . PHP_EOL;
30echo $serializedData . PHP_EOL . PHP_EOL;
31
32// 3. 新しい空の SplDoublyLinkedList オブジェクトを作成します。
33$unserializedList = new SplDoublyLinkedList();
34
35// unserialize メソッドを使って、シリアライズされたデータからリストを復元します。
36// string $data を引数に取り、オブジェクトの状態を復元します。戻り値はありません。
37$unserializedList->unserialize($serializedData);
38
39echo "--- unserialize で復元されたリストの内容 ---" . PHP_EOL;
40// 復元されたリストの内容を一つずつ出力して確認
41foreach ($unserializedList as $item) {
42    echo (is_array($item) ? json_encode($item) : $item) . PHP_EOL;
43}
44echo PHP_EOL;
45
46// 4. 復元された SplDoublyLinkedList を配列に変換し、JSON 形式で出力します。
47// SplDoublyLinkedList は Traversable インターフェースを実装しているため、
48// iterator_to_array() 関数で簡単に配列に変換できます。
49$listAsArray = iterator_to_array($unserializedList);
50
51// 配列を JSON 形式の文字列に変換します。
52// JSON_PRETTY_PRINT は出力を整形し、JSON_UNESCAPED_UNICODE はマルチバイト文字をエスケープせずに表示します。
53$jsonOutput = json_encode($listAsArray, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
54
55echo "--- 復元されたリストを JSON に変換 ---" . PHP_EOL;
56echo $jsonOutput . PHP_EOL;
57
58?>

PHPのSplDoublyLinkedList::unserializeメソッドは、以前にserialize関数で文字列化されたSplDoublyLinkedListオブジェクトの状態を、再びオブジェクトとして復元するための機能です。

このサンプルコードでは、まずSplDoublyLinkedListオブジェクトを作成し、複数の要素を追加しています。その後、serialize()関数を使って、このオブジェクト全体をバイトストリーム形式の文字列に変換します。この文字列は、オブジェクトの構造とデータを保存するのに適しています。

次に、新しく空のSplDoublyLinkedListオブジェクトを作成し、そのオブジェクトのunserializeメソッドを呼び出します。このメソッドは、引数として先ほどシリアライズした文字列$dataを受け取ります。受け取った文字列データに基づいて、呼び出し元のオブジェクトの状態を完全に復元します。このメソッドは復元されたオブジェクトを直接返すのではなく、呼び出し元のオブジェクト自身の状態を更新するため、戻り値はありません。

復元されたリストは、元のリストと全く同じ内容と順序を持っています。最後に、この復元されたSplDoublyLinkedListを通常のPHP配列に変換し、json_encode()関数を使ってJSON形式の文字列として出力しています。これは、unserializeで復元したデータを、Webサービスなどで広く利用されるJSON形式に変換し、外部システムとの連携に活用する一般的な方法を示しています。

SplDoublyLinkedList::unserializeメソッドは、呼び出したオブジェクト自身の状態を引数で渡されたデータに基づいて上書きします。戻り値がないため、メソッド実行後に元のオブジェクトが復元された内容に変わる点にご注意ください。

外部から取得した信頼できないシリアライズデータをunserializeすると、意図しないコード実行など重大なセキュリティリスクにつながる可能性があります。必ず信頼できるソースのデータにのみ使用してください。

復元されたデータが期待通りの内容になっているか確認することも大切です。本番環境で利用する際には、不正なデータが渡された場合のエラーハンドリングや入力値検証も考慮する必要があります。

関連コンテンツ