【PHP8.x】Serializable::unserialize()メソッドの使い方
unserializeメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
unserializeメソッドは、PHPのSerializableインターフェースを実装したクラスにおいて、オブジェクトの逆シリアライズ(復元)を実行するメソッドです。このメソッドは、外部から受け取ったシリアライズされたデータ(文字列形式)を基に、現在のオブジェクトの状態を再構築するために使用されます。通常、開発者がこのメソッドを直接呼び出すことはなく、PHPの組み込み関数であるunserialize()が、Serializableインターフェースを実装したオブジェクトを復元する際に、内部的に自動でこのメソッドを呼び出します。
unserializeメソッドは、$serializedという名前の引数を一つ受け取ります。この引数には、対象のオブジェクトが以前にシリアライズされた際のデータが文字列として渡されます。開発者がこのメソッドを実装する主な目的は、オブジェクトのプロパティをどのように復元するかについて、カスタムのロジックを細かく制御することにあります。
例えば、オブジェクトがファイルハンドルやデータベース接続といったリソースを保持していた場合、シリアライズ時にはこれらのリソース自体は保存できません。そのため、unserializeメソッド内で、これらのリソースを再接続したり、復元時に特定のデータを変換したりする処理を記述することができます。メソッドの実装では、受け取った$serializedデータを利用して、現在のオブジェクトのプロパティに適切な値を設定し、オブジェクトを有効な状態に戻す処理を記述します。これにより、オブジェクトはシリアライズされる前の状態に正確に復元され、アプリケーション内で利用できるようになります。
構文(syntax)
1public function unserialize(string $data): void
引数(parameters)
string $data
- string $data: シリアライズされたPHP値を含む文字列
戻り値(return)
戻り値なし
戻り値はありません
サンプルコード
PHP unserialize エラーハンドリングする
1<?php 2 3/** 4 * unserialize() 関数を使ったデータの復元とエラーハンドリングの例。 5 * 6 * PHP 8において、不正なシリアライズデータが与えられた場合に、 7 * unserialize() 関数が false を返し、警告 (E_WARNING) を発生させることを示します。 8 * SerializableインターフェースはPHP 8では削除されているため、グローバルな unserialize() 関数を使用します。 9 */ 10function demonstrateUnserializeErrorHandling(): void 11{ 12 // unserialize() 関数でオブジェクトを復元する際には、 13 // 元のクラス定義が利用可能である必要があります。 14 // このデモのためにシンプルなクラスを定義します。 15 if (!class_exists('DemoClassForUnserialize')) { 16 class DemoClassForUnserialize 17 { 18 public string $message; 19 20 public function __construct(string $message = 'Default Message') 21 { 22 $this->message = $message; 23 } 24 } 25 } 26 27 echo "--- 正しいシリアライズデータの例 ---\n"; 28 $originalObject = new DemoClassForUnserialize('Hello PHP 8'); 29 $serializedData = serialize($originalObject); 30 echo "元のシリアライズデータ: " . $serializedData . "\n"; 31 32 // 正しいデータを unserialize します。 33 $restoredObject = unserialize($serializedData); 34 35 if ($restoredObject === false) { 36 // 通常、正しいデータでは unserialize() は false を返しません。 37 echo "エラー: 予期せず unserialize() に失敗しました。\n"; 38 } elseif ($restoredObject instanceof DemoClassForUnserialize) { 39 echo "成功: オブジェクトが正しく復元されました。\n"; 40 echo "復元されたオブジェクトのメッセージ: " . $restoredObject->message . "\n"; 41 } else { 42 echo "警告: 予期しない型のデータが復元されました。\n"; 43 var_dump($restoredObject); 44 } 45 46 echo "\n--- 不正なシリアライズデータの例 ---\n"; 47 // 不正なシリアライズデータ(意図的に途中で切断されています) 48 // このようなデータは unserialize() によって E_WARNING を発生させ、false を返します。 49 $invalidSerializedData = 'O:22:"DemoClassForUnserialize":1:{s:7:"message";s:11:"Hello PHP 8";s:'; 50 echo "不正なシリアライズデータ: " . $invalidSerializedData . "\n"; 51 52 // 不正なデータを unserialize します。 53 // この行の実行時にPHPは警告 (E_WARNING) を発生させ、 54 // $resultOfInvalidData には false が格納されます。 55 $resultOfInvalidData = unserialize($invalidSerializedData); 56 57 if ($resultOfInvalidData === false) { 58 echo "エラー: 不正なシリアライズデータのため unserialize() に失敗しました。\n"; 59 echo "(PHPの警告メッセージを確認してください。例: unserialize(): Error at offset ...)\n"; 60 } else { 61 echo "警告: 不正なデータが予期せず復元されてしまいました。\n"; 62 var_dump($resultOfInvalidData); 63 } 64 65 echo "\n--- 全く関係のない文字列の例 ---\n"; 66 $randomString = "This is not a valid serialized string at all."; 67 echo "ランダムな文字列: " . $randomString . "\n"; 68 69 // 全くシリアライズ形式に合致しない文字列も unserialize() は false を返します。 70 $resultOfRandomString = unserialize($randomString); 71 72 if ($resultOfRandomString === false) { 73 echo "エラー: ランダムな文字列のため unserialize() に失敗しました。\n"; 74 echo "(PHPの警告メッセージも確認してください。)\n"; 75 } else { 76 echo "警告: ランダムな文字列が予期せず復元されてしまいました。\n"; 77 var_dump($resultOfRandomString); 78 } 79} 80 81// サンプル関数の実行 82demonstrateUnserializeErrorHandling();
PHP 8のunserialize関数は、serialize関数によって文字列化されたデータを元のPHPの変数やオブジェクトの状態に復元するために使用されます。引数string $dataには、復元したいシリアライズ済みの文字列データを渡します。
この関数は、復元に成功した場合は元のデータ型(配列やオブジェクトなど)を返します。しかし、与えられた$dataが破損していたり、シリアライズ形式として正しくない場合、unserialize関数は警告(E_WARNING)を発生させるとともに、falseを返します。このfalseの戻り値を確認することで、データ復元が失敗したかどうかを判断し、適切にエラーをハンドリングすることが重要です。
サンプルコードでは、まず正しいシリアライズデータを使ってオブジェクトが正常に復元される様子を示します。次に、意図的に破損させた不正なシリアライズデータや、全く関係のない文字列をunserialize関数に渡した例を紹介しています。これらの不正なケースでは、PHPが警告を出力し、関数がfalseを返すことで、プログラム側でエラーを検知し対処できることが明確に示されています。unserialize関数を利用する際は、常にfalseが返される可能性を考慮し、復元された値のチェックを怠らないようにしてください。
unserialize()関数は、PHP 8ではグローバル関数として提供され、Serializableインターフェースのメソッドではありません。この関数は、不正なシリアライズデータや無効な文字列を与えられると、警告(E_WARNING)を発生させ、戻り値としてfalseを返します。そのため、必ずif ($result === false)のように戻り値をチェックし、適切にエラー処理を行うことが重要です。オブジェクトを復元する場合、unserialize()を実行する前に、そのオブジェクトの元のクラス定義が利用可能である必要があります。また、この関数は悪意のあるデータが実行されるセキュリティリスクを伴うため、信頼できないソースからの入力データには絶対に使用しないでください。リファレンス情報では「戻り値なし」とありますが、実際には復元されたデータまたはfalseが返されますのでご注意ください。
PHP unserializeで配列を復元する
1<?php 2 3/** 4 * PHPのunserialize関数を使用して、シリアライズされた配列を元の状態に復元するサンプルコードです。 5 * 6 * この関数は以下の手順で動作します。 7 * 1. 元となるPHPの配列を定義します。 8 * 2. `serialize()` 関数を使って、その配列を文字列形式に変換(シリアライズ)します。 9 * 3. `unserialize()` 関数を使って、シリアライズされた文字列を元の配列に復元(デシリアライズ)します。 10 * 4. 復元された配列が元の配列と一致するかどうかを確認し、結果を出力します。 11 * 12 * `unserialize`は、保存されたデータやネットワーク経由で転送されたデータを、 13 * PHPの変数として再利用する際によく利用されます。 14 */ 15function demonstrateArrayUnserialization(): void 16{ 17 // 1. 元の配列を定義します。 18 $originalArray = [ 19 'id' => 101, 20 'name' => '田中 太郎', 21 'email' => 'taro.tanaka@example.com', 22 'roles' => ['admin', 'editor'], 23 'isActive' => true 24 ]; 25 26 echo "--- 元の配列 ---\n"; 27 print_r($originalArray); 28 echo "\n"; 29 30 // 2. 配列をシリアライズ(文字列に変換)します。 31 // serialize()は、PHPの値を保存可能な文字列形式に変換します。 32 $serializedString = serialize($originalArray); 33 34 echo "--- シリアライズされた文字列 ---\n"; 35 echo $serializedString . "\n"; 36 echo "\n"; 37 38 // 3. シリアライズされた文字列をunserialize(元の配列に復元)します。 39 // unserialize()は、serialize()で生成された文字列を元のPHPの値に復元します。 40 // 戻り値はmixed型であり、元の配列やオブジェクト、スカラ値などになります。 41 $unserializedArray = unserialize($serializedString); 42 43 echo "--- unserializeで復元された配列 ---\n"; 44 print_r($unserializedArray); 45 echo "\n"; 46 47 // 4. 復元された配列が元の配列と一致するか確認します。 48 if ($originalArray === $unserializedArray) { 49 echo "✅ 配列は正しくシリアライズされ、元の状態に復元されました。\n"; 50 } else { 51 echo "❌ 配列の復元に失敗しました。\n"; 52 } 53} 54 55// 関数を実行して、unserializeの動作を確認します。 56demonstrateArrayUnserialization(); 57 58?>
PHPのunserialize関数は、serialize関数によって文字列形式に変換(シリアライズ)されたPHPのデータを、元の状態に復元(デシリアライズ)するために使用されます。
このサンプルコードでは、最初に定義されたPHPの配列をserialize関数で文字列に変換しています。その後、生成されたシリアライズ済み文字列をunserialize関数に引数として渡すことで、元の配列の状態に正確に復元する過程を示しています。
unserialize関数は、引数として復元したいシリアライズ済みデータを含む文字列$dataを受け取ります。そして、その文字列を解析し、元のPHPのデータ型(この例では配列)として復元された値を返します。この戻り値は、元の配列、オブジェクト、数値、真偽値など、元のデータ型に応じたmixed型となります。
復元された配列が元の配列と厳密に一致するかを確認することで、unserialize関数が正しく機能していることを検証しています。この関数は、データベースに保存された複雑なデータや、ネットワーク経由で送受信されるデータをPHPプログラム内で元のデータ構造として再利用する際に非常に役立ちます。
この関数は、信頼できない外部からのシリアライズされた文字列を処理すると、セキュリティ上の重大な脆弱性を引き起こす可能性があります。そのため、unserializeは必ず信頼できる安全なデータソースから取得した文字列に対してのみ使用してください。予期せぬ文字列が入力された場合、unserializeは期待通りの値を返さず、falseを返すか、警告を発生させることがありますので、必ず戻り値の厳密な確認が必要です。配列だけでなく、オブジェクトや他のPHPのデータ型も復元できますが、その際もセキュリティリスクは常に意識し、入力データの検証を徹底することが重要です。安全なシステム開発のために、この点を特にご注意ください。
PHPのunserializeからJSONを生成する
1<?php 2 3/** 4 * Serializableインターフェースを実装したサンプルクラス。 5 * このクラスは、自身をシリアライズ可能な形式に変換し、またシリアライズされたデータから自身を復元する方法を定義します。 6 * 7 * 注意: PHP 8ではSerializableインターフェースは非推奨となっており、 8 * 代替として __serialize() および __unserialize() マジックメソッド、 9 * または JsonSerializable インターフェースの使用が推奨されています。 10 * しかし、リファレンス情報に基づき、ここではSerializableインターフェースの実装例を示します。 11 */ 12class UserProfile implements Serializable 13{ 14 private string $username; 15 private int $userId; 16 private array $preferences; 17 18 /** 19 * コンストラクタ。UserProfileオブジェクトを初期化します。 20 * 21 * @param string $username ユーザー名 22 * @param int $userId ユーザーID 23 * @param array $preferences ユーザー設定 24 */ 25 public function __construct(string $username, int $userId, array $preferences = []) 26 { 27 $this->username = $username; 28 $this->userId = $userId; 29 $this->preferences = $preferences; 30 } 31 32 /** 33 * オブジェクトの現在の状態をシリアライズし、文字列として返します。 34 * PHPの組み込み関数 serialize() がこのオブジェクトを処理する際に、このメソッドが自動的に呼び出されます。 35 * 36 * @return string オブジェクトのシリアライズされたデータ 37 */ 38 public function serialize(): string 39 { 40 // オブジェクトのプロパティを連想配列としてまとめ、PHPの組み込み serialize() 関数でシリアライズします。 41 return serialize([ 42 'username' => $this->username, 43 'userId' => $this->userId, 44 'preferences' => $this->preferences, 45 ]); 46 } 47 48 /** 49 * シリアライズされたデータからオブジェクトの状態を復元します。 50 * PHPの組み込み関数 unserialize() がこのオブジェクトを復元する際に、このメソッドが自動的に呼び出されます。 51 * 52 * リファレンス情報にある通り、このメソッド自体の戻り値は「戻り値なし (void)」です。 53 * メソッド内でオブジェクトのプロパティを更新することで状態を復元します。 54 * 55 * @param string $data シリアライズされたデータ文字列 56 * @return void 57 */ 58 public function unserialize(string $data): void 59 { 60 // シリアライズされたデータをPHPの組み込み unserialize() 関数でデシリアライズします。 61 $unserializedData = unserialize($data); 62 63 // デシリアライズされたデータを使って、現在のオブジェクトのプロパティを復元します。 64 // 未定義のキーがないように、null合体演算子 (??) を使用してデフォルト値を提供します。 65 $this->username = $unserializedData['username'] ?? 'Guest'; 66 $this->userId = $unserializedData['userId'] ?? 0; 67 $this->preferences = $unserializedData['preferences'] ?? []; 68 } 69 70 /** 71 * オブジェクトのデータを連想配列として取得します。 72 * このメソッドは、オブジェクトのデータをJSON形式に変換する際に役立ちます。 73 * 74 * @return array オブジェクトのプロパティを表す連想配列 75 */ 76 public function toArray(): array 77 { 78 return [ 79 'username' => $this->username, 80 'user_id' => $this->userId, 81 'preferences' => $this->preferences, 82 ]; 83 } 84} 85 86// --- PHPのunserialize関数を使用したシリアライズデータの復元とJSON変換のサンプル --- 87 88// 1. オリジナルのUserProfileオブジェクトを作成します。 89$originalUserProfile = new UserProfile('Alice Smith', 1001, ['theme' => 'dark', 'notifications' => true]); 90 91// 2. オブジェクトをPHPの組み込みserialize()関数でシリアライズします。 92// この時、UserProfile::serialize() メソッドが内部的に呼び出されます。 93$serializedString = serialize($originalUserProfile); 94 95echo "--- シリアライズされたデータ (PHP形式) ---" . PHP_EOL; 96echo $serializedString . PHP_EOL . PHP_EOL; 97 98// 3. シリアライズされた文字列をPHPの組み込みunserialize()関数でデシリアライズ(復元)します。 99// この時、UserProfile::unserialize() メソッドが内部的に呼び出され、 100// unserialize() 関数自体は復元されたオブジェクトを返します。 101$restoredUserProfile = unserialize($serializedString); 102 103echo "--- 復元されたオブジェクトのデータ ---" . PHP_EOL; 104if ($restoredUserProfile instanceof UserProfile) { 105 // toArray() メソッドを使って、復元されたオブジェクトのデータを連想配列として取得し表示します。 106 print_r($restoredUserProfile->toArray()); 107} else { 108 echo "エラー: オブジェクトの復元に失敗しました。" . PHP_EOL; 109} 110echo PHP_EOL; 111 112// 4. 復元されたオブジェクトのデータをJSON形式に変換します。 113if ($restoredUserProfile instanceof UserProfile) { 114 // toArray() で取得した配列を json_encode() 関数でJSON文字列に変換します。 115 // JSON_PRETTY_PRINT は、読みやすいようにJSONを整形するためのオプションです。 116 $jsonOutput = json_encode($restoredUserProfile->toArray(), JSON_PRETTY_PRINT); 117 118 echo "--- 復元されたデータから生成されたJSON形式 ---" . PHP_EOL; 119 echo $jsonOutput . PHP_EOL; 120} 121
PHPのSerializableインターフェースは、オブジェクトの状態を文字列化(シリアライズ)し、その文字列から元のオブジェクトに復元(デシリアライズ)する機能を提供します。サンプルコードでは、UserProfileクラスがこのインターフェースを実装し、特にunserializeメソッドの動作に焦点を当てています。
Serializable::unserializeメソッドは、シリアライズされたデータ文字列を受け取り、そのデータに基づいてオブジェクト自身のプロパティを復元する役割を担います。引数 $data には、serializeメソッドによって生成されたオブジェクトの状態を表す文字列が渡されます。このメソッドの戻り値はvoid(何も返さない)です。これは、新しいオブジェクトを返すのではなく、メソッドが呼び出された既存のオブジェクトの内部状態を直接更新して復元するためです。
まずUserProfileオブジェクトを作成し、PHPの組み込み関数serialize()で文字列化します。この時、UserProfile::serialize()メソッドが内部的に呼び出されます。次に、この文字列をPHPの組み込み関数unserialize()に渡すと、UserProfile::unserialize()メソッドが自動的に呼び出され、文字列内のデータからオブジェクトのプロパティが復元されます。復元されたオブジェクトのデータをtoArray()メソッドで配列に変換後、json_encode()関数でJSON形式に出力し、データの活用方法を示しています。PHP 8ではSerializableインターフェースは非推奨ですが、リファレンスに基づきその挙動を解説しています。
PHP 8では、Serializableインターフェースは非推奨であり、__serialize()や__unserialize()マジックメソッド、またはJsonSerializableインターフェースの使用が推奨されています。
特に、unserialize関数は信頼できない外部からのデータに使用すると、「オブジェクトインジェクション」という深刻なセキュリティ脆弱性を引き起こす可能性があります。そのため、利用は極力避け、安全性が確保された内部データに限定してください。
サンプルコードのunserializeメソッド自体はオブジェクト内部の状態を復元し戻り値はありませんが、PHP組み込みのunserialize関数は復元されたオブジェクトを返します。
また、PHPのシリアライズデータはJSONとは異なる形式のため、相互に直接変換することはできません。JSONとして扱いたい場合は、toArray()メソッドのようにデータを配列に変換してからjson_encode()関数を使用してください。