PHPからMySQLを使っていたとき・・
- どうしても配列を格納したい
- あれ?でもどうやって?
- MySQLに配列型なんてないし...
そう悩む場面がありました。
でも工夫次第でなんとでもなります。
そこで PHP+MySQLで配列格納する方法 を2つ紹介!
コード例と一緒に載せておきます。
このページの目次
方法1.CSVとして疑似的な配列として格納
まず1つめはCSVとして格納する方法
※ CSV = Comma Separated Values
CSVについての説明は不要ですよね。
具体的な方法は次のような感じ
1.テーブルを作る
▼ 例として次のテーブルを作成
1 2 3 4 5 |
CREATE TABLE group_list ( id INT AUTO_INCREMENT, members_csv VARCHAR(1024), PRIMARY KEY(id) ); |
このSQLの members_csv はただの可変長文字列(長さは任意)です。ここにCSVを格納することで疑似的に配列を保存してみようと思います。
2.PHPのmysqliを使って配列を格納・取得
▼ 配列をCSVとして格納するコード例
1 2 3 4 5 6 7 8 9 10 11 12 |
/// 配列をCSVとしてDBに保存 $members = ['hoge', 'fuga', 'piyo']; $members_csv = implode(',', $members); $sql = " INSERT INTO group_list ( members_csv ) VALUES ( ? ); "; $stmt = $mysqli->prepare($sql); $stmt->bind_param('s', $members_csv); $stmt->execute(); $stmt->close(); |
▼ 配列をCSVから取得するコード例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
/// 配列をCSVとしてDBから取得 $sql = " SELECT members_csv FROM group_list LIMIT 1 "; $stmt = $mysqli->prepare($sql); $stmt->execute(); $stmt->bind_result($members_csv); $stmt->fetch(); $stmt->close(); /// CSV文字列を元の配列に復元する $members = explode(',', $members_csv); echo '$members : ' . var_export($members,1); |
▼ 上コードの出力結果
1 2 3 4 5 |
$members : array ( 0 => 'hoge', 1 => 'fuga', 2 => 'piyo' ) |
しっかりと格納・取得ができてます。
この方法の使いどころは次の場面
- 単純な配列を格納するだけでいい
- 連想配列などを扱っていない
もし複雑なデータ(連想配列とか入れ子構造になってる配列とか)も格納したい場合、2つめのJSONを使った格納方法がベストだと思います。
方法2.JSON文字列で配列・連想配列を格納
2つめは1つめより汎用的な方法
JSON(文字列)を使って保存します。
▼ 説明不要だけど念のため...
JavaScript Object Notation(JSON、ジェイソン)はデータ記述言語の1つである。軽量なテキストベースのデータ交換用フォーマットでありプログラミング言語を問わず利用できる[1]。名称と構文はJavaScriptにおけるオブジェクトの表記法に由来する。
引用元 : https://ja.wikipedia.org/wiki/JavaScript_Object_Notation
多くの言語がサポートしているデータ形式
だからPHPに限らず汎用的に配列格納できます。
その具体的なコード例は次の通り
1.配列格納するテーブルを作成
▼ 例として次SQLからテーブル作成
1 2 3 4 5 |
CREATE TABLE group_list ( id INT AUTO_INCREMENT, members_json VARCHAR(1024), PRIMARY KEY(id) ); |
この中の members_json がJSONを格納するためのカラム。このように末尾に _json とつけておくと「このテーブルってただの文字列?」のような誤解をなくせます。
2.PHPのmysqliから配列を格納・取得
▼ 連想配列をJSONとして格納するコード例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/// 配列をJSONとしてDB保存する $members = [ ['name' => 'hoge'], ['name' => 'fuga'], ['name' => 'piyo'] ]; $json = json_encode($members); $sql = " INSERT INTO group_list ( members_json ) VALUES ( ? ) "; $stmt = $mysqli->prepare($sql); $stmt->bind_param('s', $json); $stmt->execute(); $stmt->close(); |
▼ JSONとして配列取得するコード例
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/// 配列をJSONとしてDBから取得 $sql = " SELECT members_json FROM group_list LIMIT 1 "; $stmt = $mysqli->prepare($sql); $stmt->execute(); $stmt->bind_result($json); $stmt->fetch(); $stmt->close(); $members = json_decode($json, true); echo '$members : ' . var_export($members,1); |
▼ 上コードの出力結果
1 2 3 4 5 |
$members : array ( 0 => array ( 'name' => 'hoge', ), 1 => array ( 'name' => 'fuga', ), 2 => array ( 'name' => 'piyo', ), ) |
問題なく配列の格納・取得ができてます。
この方法の利点は次のようなところ
- 入れ子の配列にも対応できる
- オブジェクトの格納できる
- いろいろと汎用性が高くて便利
配列を格納したいけど「もっと複雑な構造になるかもしれない」、「なるべく汎用的にしたいな」と言った場合、1つめのCSVを使う方法より確実性が高いですね。
方法3.searialize・unserializeで配列格納
PHPではデータをシリアライズ化できます。
次の2つの関数を使うことで可能。
▼ serialize関数の解説
serialize ( mixed $value ) : string
値の保存可能な表現を生成します。型や構造を失わずに PHP の値を保存または渡す際に有用です。シリアル化された文字列を PHP の値に戻すには、 unserialize() を使用してください。
▼ unserialize関数の解説
unserialize ( string $str [, array $options ] ) : mixed
unserialize() は、シリアル化された変数を PHP 変数値に戻す変換を行います。
引用元 : https://www.php.net/manual/ja/function.unserialize.php
これもコード例を紹介・・・
と思ったけど面倒くさいので省略します。
ここまでのコードを少し改造するだけです。
方法4.テーブル設計自体を見直しする
そもそも配列を直接DB保存することは少ないです。
▼ 次の場合はテーブル設計を見直すべきかも
- 複雑なデータを配列・JSONで保存したい
- 複数要素のある連想配列を保存したい
そういう場合は新しくテーブルを作った方が見通しが良くなります。配列として直接保存するより検索・新規追加・更新も楽です。
ここまで具体的に1~3の方法を提示しましたが、第4の方法として「配列ではなく別テーブルとして独立させる」ことを考えるのも手ですね。
方法5.MySQL5.7からJSON型が使用可能
MySQLでついにJSON型がサポートされました。
使えるのはMySQL5.7.8以降の模様です。
▼ 格納方法・SQL例・使いどころは次記事参照
▼ JSON型でできること一覧
- 文字列ではなくJSON自体が格納可能
- 構文チェック込みでJSONを格納できる
- JSON内部の特定キーだけ部分更新可能
- JSON内部の特定キーの値をインクリメント
- JSON操作系関数もかなり充実している
箇条書きでは説明できないほど便利です。
詳しく知りたい人は上記記事をご覧ください。
もちろんJSON型は乱用すべきものではありません。
その判別ができるなら、JSON型はすごく強力です。
配列を格納する方法のまとめ
紹介した方法は次の3つ(+2つ)
もし間違いを発見されたらコメントでご指摘を。
以上、PHP+MySQLで配列格納でした。ではまた