シリアライズとアンシリアライズについて
データベースに配列データを保存する時、データの形式が固定ならカラムとして持たせてしまえば良いんですが、データ構造が場合によって変わることもあると思います。
例えば、賃貸検索サービスのサイト内で検索が行われた時の検索条件の履歴データを保存したい時
都道府県だけで絞り込む人も居れば、駅を複数選択して沿線で探す人も居るでしょう。
こだわり検索条件を組み合わせて、〇〇駅と〇〇駅から徒歩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)
今回はシリアライズについて説明させてもらいました。
もしお困りごとがありましたら、お問い合わせフォームよりご相談ください。