CommentOut

シリアライズとアンシリアライズについて シリアライズとアンシリアライズについて

シリアライズとアンシリアライズについて

公開日:  最終更新日:

データベースに配列データを保存する時、データの形式が固定ならカラムとして持たせてしまえば良いんですが、データ構造が場合によって変わることもあると思います。

例えば、賃貸検索サービスのサイト内で検索が行われた時の検索条件の履歴データを保存したい時
都道府県だけで絞り込む人も居れば、駅を複数選択して沿線で探す人も居るでしょう。
こだわり検索条件を組み合わせて、〇〇駅と〇〇駅から徒歩10分以内のバス・トイレ別などという条件で検索する人も居るでしょう。

それらの様々な条件を検索条件ログとして持たせる時、データを連想配列化した後、シリアライズしてデータベースに保存しておくのが便利です。

シリアライズとは

シリアライズとは、”様々な構造のデータ”を”一定のフォーマットデータ”に変換したものを指します。
データを直列化することを意味します。

配列をシリアライズする方法

配列をシリアライズする場合、serialize()という関数が用意されています。
引数もシリアライズしたい配列を渡すだけなので、覚えることが少なく、簡単です。

<?php
// シリアライズ化する元データ
$search = array(
    "pref" => 1,
    "station" => array(12, 15),
    "station_range" => 2,
    "other" => array(
        "bath" => 2
    ),
);

// シリアライズを行う
$serialize = serialize($search);

// 表示
var_dump($serialize);

serialize()を実行すると、戻り値でシリアライズ化されたstring型データが取得できます。

シリアライズの形式

配列をシリアライズすると、以下のような形式に変換されます。

string(117) "a:4:{s:4:"pref";i:1;s:7:"station";a:2:{i:0;i:12;i:1;i:15;}s:13:"station_range";i:2;s:5:"other";a:1:{s:4:"bath";i:2;}}"

シリアライズ化されたデータにはデータ形式のルールがあります。

a:4:{~~~};

“a”は配列であることを表します。
a:4は要素を4つ持つ配列を表しています。
配列の中身は{}の中に定義されます。

i:1;

“i”は数字であることを表します。
なので、i:1は”数字の1″が値として入っていることを表しています。

s:4:"pref";

“s”は文字列であることを表します。
s:4は”4桁の文字列”であることを表しています。
s:4:”pref”;なので、4文字であってますね。
※文字列の囲みはダブルクォテーションであることに注意してください。

シリアライズされたデータを戻す方法

シリアライズを戻すのも簡単です。
unserialize()という関数が用意されています。

<?php
// シリアライズ化されたデータ
$serialize_data = "a:4:{s:4:"pref";i:1;s:7:"station";a:2:{i:0;i:12;i:1;i:15;}s:13:"station_range";i:2;s:5:"other";a:1:{s:4:"bath";i:2;}}"

// シリアライズを戻す関数
$unserialize = unserialize($serialize);

// 表示
var_dump($unserialize);

シリアライズ文字列の形式を変えてみるとunserializeした時どうなる?

以下のデータを元に、実験していきたいと思います。

a:2:{s:4:"pref";i:1;s:7:"station";a:2:{i:0;i:12;i:1;i:15;}}

シリアライズデータの”a”の数を変えてみる

“a”を本来の要素数「2」よりも増やした場合。今回は3にしました。

a:3:{s:4:"pref";i:1;s:7:"station";a:2:{i:0;i:12;i:1;i:15;}}

結果はWarningが表示され、シリアライズを戻すのにも失敗しています。
シリアライズで配列を作るときに、3番目の要素がundefinedになるからだろうか。

Warning: PHP Request Startup: Unexpected end of serialized data in php-wasm run script on line 5
Warning: PHP Request Startup: Error at offset 58 of 59 bytes in php-wasm run script on line 5
bool(false)

では、逆に元の要素数「2」を減らして「1」にしてみたら?
減らすだけなので、部分的に複合されるのではないか?というのが私の予想です。

a:3:{s:4:"pref";i:1;s:7:"station";a:2:{i:0;i:12;i:1;i:15;}}

しかし、こちらもダメでした。

Warning: PHP Request Startup: Error at offset 20 of 59 bytes in php-wasm run script on line 5
bool(false)

シリアライズデータの文字列の囲み記号を変えてみる

PHPの場合、文字列の囲みは””(ダブルクォーテーション)、”(シングルクォーテーション)、“(バッククォート)が使えます。
INSERTするSQLをPHPで記述する時、文字列内に上記の記号が使われている場合、囲み記号を変えることはよくあります。

では、シリアライズの文字の囲いをダブルクォーテーションからシングルクォーテーションにしてみては?

a:2:{s:4:'pref';i:1;s:7:'station';a:2:{i:0;i:12;i:1;i:15;}}

こちらについてもWarningが表示され、配列に変換されなくなってしまいました。

Warning: PHP Request Startup: Error at offset 5 of 59 bytes in php-wasm run script on line 5
bool(false)

バッククォートだとどうでしょうか?

a:2:{s:4:`pref`;i:1;s:7:`station`;a:2:{i:0;i:12;i:1;i:15;}}

こちらもダメですね。シリアライズデータの文字列囲みは””(ダブルクォーテーション)しか使えないようです。

Warning: PHP Request Startup: Error at offset 5 of 59 bytes in php-wasm run script on line 5
bool(false)

今回はシリアライズについて説明させてもらいました。

宣伝
WordPressサイトのテンプレート編集やトラブル対応、バグ修正、簡単なJavascriptの作成(カルーセルやバリデーション等)など、小規模なスポット対応を受け付けております。
もしお困りごとがありましたら、お問い合わせフォームよりご相談ください。

この記事を書いた人

uilou

uilou

プログラマー

基本的に、自分自身の備忘録のつもりでブログを書いています。 自分と同じ所で詰まった人の助けになれば良いかなと思います。 システムのリファクタリングを得意としており、バックエンド、フロントエンド、アプリケーション、SQLなど幅広い知識と経験があります。 広いだけでなく、知識をもっと深堀りしていきたいですね。