Help us understand the problem. What is going on with this article?

laravelでmysqlのjson型の扱いかた

More than 1 year has passed since last update.

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

haruraruru
PHPでお仕事してます。PythonとVue.jsもつかうことになりました。 書くのが遅いです。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away