LoginSignup
50
41

More than 3 years have passed since last update.

laravelでmysqlのjson型の扱いかた

Last updated at Posted at 2019-02-15

json型の扱いについてまとまったページがあまりなかったので書くことにしました。
・・・いまだに苦しめられています。

環境
larave5.7
Mysql5.7

1.データベースにjson型を含むテーブルをmigrationで作成するとき

 public function up()
    {
        Schema::create('members', function (Blueprint $table) {
            $table->uuid('id');
            $table->string('name', 100);
            $table->json('data')->nullable(); // ココ
            $table->timestamps();
            $table->primary('uuid');
        });
    }

※注意
なんと、Mysql5.7のJson型は初期値を設定できない仕様になっています・・・!(MariaDBは初期値OK)
$table->json('data')->default('{"title":1,"permission":[1,2]}');というかんじに書いてたらmigrate実行時にエラーが出ました。
MariaDBで開発してるけどリリース先の環境はMysqlって場合は特に気をつけてください。(もちろんDB揃えられるなら揃えてください!)

2.データベースにデータを入れるとき

こちらにすでに書かれてましたhttps://qiita.com/kamikosi/items/7d4135ce74de8b91e721


$data = [
    [
        'title' => 1,
        'permission' => [
            1,
            2,
        ],
    ],
    [
        'title' => 2,
        'permission' => [
            1,
            2,
        ],
    ]
];
$member = new Member;
$member->data = $data; // ココ
$member->save();

※注意
$member->data = json_encode($data);と書くとstringとしてデータが入ってしまう。
↓がそのjson_encodeしてしまったデータ。
"{\"permission_list\":[{\"title\":\"2\",\"permission\":[\"1\",\"3\"]}],\"admin\":false}"
JSON_UNESCAPED_UNICODEオプションを付けても両端の"はのこってしまうので
json型として取得できなくなってしまう。。。

3.データベースからデータを取得するとき

参考:https://qiita.com/pinekta/items/93c9c427ccc22df578a5

まず、モデル側に$castsを設定する。


class Member extends Eloquent
{
    protected $casts = [
        'json_column' => 'json',  // ココ
    ];
}

$castsについてはjson型だけでなく、データをDBから取得するときの型を設定できるものなので
知っておくと応用がききそうです。

つぎにそのモデルを使ってデータを取得します。

$member = Member::find($id);
// $member->dataにはjsonが連想配列として保存されている
$data_permission = isset($member->data['permission']) ? $member->data['permission'] : null ;

$castsによってjson型データが連想配列として取得できるようになっているので
$member->data['permission']のように取得できる。
json objectとしてデータベースに入れていても、取得すると連想配列になっているのでネスト地獄に注意。。。(絶賛苦戦中)

また1.の注意欄でも書いた通り、初期値設定ができないので
特定のキーが存在するかどうかのチェック(こちらではissetを使用)が必要です。


まだまだlaravel, MysqlのJson型については勉強中の身ですので
「こうすれば{もっとかんたんだよ|できるよ}」などのご意見をいただけましたら幸いです。

50
41
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
50
41