Лучший способ хранить и загружать JSON из базы данных в Laravel

Я пытаюсь сохранить json в базе данных и загрузить его обратно

Я пытался хранить


Хранится правильно. Я проверил БД, он показал правильно.

{имя: "Джон", возраст: 31 год, город: "Нью-Йорк"}

Я продолжал смотреть


Это мой код.

      public function store()
{

    $paste             = new Paste;
    $paste->uuid       = Str::uuid()->toString();
    $paste->data       = trim(Request::get('data',''));
    $paste->save();

    return Redirect::to('/paste/'.$paste->uuid)->with('success', 'Created');

}

public function show($uuid)
{
    $paste  = Paste::where('uuid',$uuid)->first();
    return response()->json($paste->data);
}

Какие-нибудь подсказки для меня?

Воспроизводится здесь

https://www.bunlongheng.com/paste


Попробуйте # 2

Если бы я сделал это

      public function show($uuid)
{


    $paste  = Paste::where('uuid',$uuid)->first();
    return View::make('layouts.fe.pastes.show', get_defined_vars());

}

и на мой взгляд, у меня есть только эта 1 строка

      {!!$paste->data!!}

Я получаю те же данные, что и отправил сейчас.

      {name: "John", age: 31, city: "New York"}

НО браузер обнаружил это как текст, а не как ответ JSON, который победил цель того, что я пытаюсь сделать.


Попробуйте # 3

      public function show($uuid)
{
    $paste  = Paste::where('uuid',$uuid)->first();
    return response()->json(stripslashes($paste->data));
    
}

результат



Попробуйте # 4

      public function show($uuid)
{
    $paste  = Paste::where('uuid',$uuid)->first();
    return View::make('layouts.fe.pastes.show', get_defined_vars());
}

Посмотреть

      {{ json_encode($paste->data, JSON_UNESCAPED_SLASHES) }}

результат

      "{name: \"John\", age: 31, city: \"New York\"}"

Попробуйте # 5

Я думаю, что проблема заключается в хранении ... а не в загрузке и рендеринге.

Я пытался

      return response()->json($paste);

Мой парсер JSON обнаружил это ...

      {
"id": 11,
"status": 0,
"uuid": "0c40f97d-7d98-42c6-864e-71d3ed81eed3",
"name": "n6ou",
"password": "",
"expiration": "",
"type": "json",
"data": "{name: \"John\", age: 31, city: \"New York\"}",
"created_at": "2021-04-22T22:53:11.000000Z",
"updated_at": "2021-04-22T22:53:11.000000Z"
}

Это то, что я использовал для хранения

      $paste->data       = trim(Request::get('data',''));
$paste->save();

Попробуйте # 6

Для тех из вас, кто сомневается в моих данных / содержании

Я пробовал вставить ту же строку в Pastebin

Он очищен, вы можете увидеть ниже.

https://pastebin.com/raw/r9akUK1v

5 ответов

База данных

В миграции вашей базы данных добавьте:

      $table->json('data'); // Recommended. Supported in MySQL since version 5.7.8

или же

      $table->string('data', $maxNumberOfCharecters);

Рекомендуется использовать тип столбца JSON, поскольку он позволяет выполнять SQL-запросы к данным JSON. См. Тип данных MySQL JSON

Модель: приведение атрибута

Следующая проблема заключается в том, что вам нужно иметь возможность преобразовывать свои данные в массив PHP.

Это делается путем изменения атрибута cast в модели:

      class Paste extends Model {
    protected $casts = [
        'data' => 'array'
    ];
}

Дополнительные сведения см. В разделе « Приведение массивов и JSON» .

Теперь вы можете сохранить данные в атрибуте как массив PHP, а также назначить ему массив PHP.

       $paste = Paste::first();
 dump($paste); // Returns a PHP array     

 $paste->data = ['some-data' => 20, 'score' => 500];
 $paste->save();

Внутри, когда он сохраняет данные, он автоматически преобразует их в строку JSON и сохраняет в базе данных в правильном формате.

Метод хранения

При вводе ввода как JSON это сильно зависит от того, как вы хотите передать данные,

1. Отправка данных формы с типом содержимого JSON (рекомендуется)

Я рекомендую отправлять все данные в виде JSON в теле POST следующим образом:

      Content-Type: application/json
Body:
{
   "data": {
      "name": "John",
      "age": 31,
      "city": "New York"
   },
   "someOtherField": "Hello!"
}

Ваш store() метод теперь должен быть (я также добавил код проверки):

      public function store()
{
    $this->validate($request, [
        'data' => ['required', 'array'],
        'data.*.name' => ['required', 'string'],
        'data.*.age' => ['required', 'int'],
        'data.*.city' => ['required', 'string'],
    ]);
    
    $paste = new Paste();
    $paste->uuid = Str::uuid()->toString();
    $paste->data = $request->post('data'); // No need to decode as it's already an array
    $paste->save();

    return Redirect::to("/paste/{$paste->uuid}")
        ->with('success', 'Created');
}

2. Отправка данных формы с параметрами формы

Однако, если вы настаиваете на отправке данных через параметры запроса или параметры формы, обратите внимание, что они могут отправлять только строки. Поэтому вам необходимо отправить закодированную версию строки JSON для сохранения типов данных следующим образом:

      Form Params:
- data: '{"name": "John", "age": 31, "city": "New York"}'
- someOtherField: "Hello!"

Теперь метод store будет выглядеть так:

          $this->validate($request, [
        'data' => ['required', 'json'], // I'm unsure if data is required
    ]);
    
    $data = json_decode($request->post('data')); // Needs to be decoded
    
    // validate $data is correct
    Validator::make($data, [
        'name' => ['required', 'string'],
        'age' => ['required', 'int'],
        'city' => ['required', 'string'],
    ])->validate();
    
    
    $paste = new Paste();
    $paste->uuid = Str::uuid()->toString();
    $paste->data = $data;
    $paste->save();

    return Redirect::to("/paste/{$paste->uuid}")
        ->with('success', 'Created');

Показать метод

Ваш метод показа не требует изменений:

      public function show($uuid)
{
    $paste = Paste::where('uuid', $uuid)->first();
    return response()->json($paste->data);
}

1- Ваш столбец должен иметь тип json.

      $table->json('data');

2- в вашей модели вам нужно преобразовать свой столбец в массив

        protected $casts = ['data' => 'array'];

3- отправка значения данных вашему контроллеру должна быть массивом, чтобы вы могли использовать для него проверку массива Laravel:

      [
  'data' => 'required|array',
  'data.*.name' => 'required'
   ....
]

4- когда вы сохраняете свои данные, они будут анализироваться автоматически, и то же самое, когда вы извлекаете свой столбец данных, он будет преобразован в массив

  1. С использованием ->json()в качестве метода миграции для хранения данных JSON (https://laravel.com/docs/8.x/migrations#column-method-json)
  2. См. «Приведение массивов и JSON» ( https://laravel.com/docs/8.x/eloquent-mutators#array-and-json-casting), чтобы узнать, как подготовить данные.

Я знаю, что ответ не в абзацах, как другие, но мне нравится делать его простым и прямым. Это лучшее решение? Никто не может вам этого сказать или доказать? Будет ли этот метод работать, никто не может сказать вам это или доказать это, но, по крайней мере, он повышает ваш уровень успеха. Дайте мне знать, если я могу еще чем-нибудь помочь! Удачи

Если вы хотите сохранить данные как json в БД и восстановить их, просто сделайте следующее (я всегда использую этот способ):

1- Добавьте свои данные в массив:

      $data["name"] = "John";
$data["age"] = 31;
$data["city"] = "New York";

2- Закодируйте массив и добавьте его в базу данных (вы можете сохранить его как текст)

      $encodedData = json_encode($data);

3- Если вы хотите добавить вложенные данные json, просто сделайте свой массив вложенным массивом.

4- Когда вы восстанавливаете данные, просто используйте json_decode для их декодирования

Просто добавьте это в свою модель.

      protected $casts = [
    'data' => 'object'
];

Затем вы можете получить представление следующим образом:

      {{ $data->data->name }}
Другие вопросы по тегам