在 Laravel 中从数据库存储和加载 JSON 的最佳方式
Best way to store and load JSON from database in Laravel
我正在尝试将 json 存储到数据库中并将其加载回来
我尝试存储
{name: "John", age: 31, city: "New York"}
它存储正确。我检查了数据库,它显示正确。
{name: "John", age: 31, city: "New York"}
我一直在看
"{name: \"John\", age: 31, city: \"New York\"}"
这是我的代码。
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());
}
在我看来,我只有这一行
{!!$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));
}
结果
"{name: \"John\", age: 31, city: \"New York\"}"
尝试 # 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
对于那些怀疑我的 data/content
的人
我试过在 Pastebin 中粘贴同一行
清理完毕,可以看下面
如果你想在数据库上将数据存储为 json 并恢复它,只需执行以下操作(我一直使用这种方式):
1- 将您的数据添加到数组:
$data["name"] = "John";
$data["age"] = 31;
$data["city"] = "New York";
2- 对数组进行编码并将其添加到数据库中(您可以将其存储为文本)
$encodedData = json_encode($data);
3- 如果您想添加嵌套 json 数据,只需将您的数组设为嵌套数组即可。
4- 恢复数据时只需使用 json_decode 对其进行解码
1- 您的列必须是 json 类型
$table->json('data');
2- 在您的模型中,您需要将列转换为数组
protected $casts = ['data' => 'array'];
3- 向您的控制器发送数据值必须是一个数组,以便您可以对其使用数组 Laravel 验证:
[
'data' => 'required|array',
'data.*.name' => 'required'
....
]
4- 当您存储数据时,它会被自动解析,同样当您检索数据列时,它会被转换为数组
数据库
在您的数据库迁移中添加:
$table->json('data'); // Recommended. Supported in MySQL since version 5.7.8
或
$table->text('data');
建议使用 JSON 列类型,因为它允许您对 JSON 数据执行 SQL 查询。参见 MySQL JSON Data Type
模型:投射属性
下一个问题是您需要能够将数据转换为 PHP 数组。
这是通过修改模型中的 casts 属性来完成的:
class Paste extends Model {
protected $casts = [
'data' => 'array'
];
}
有关详细信息,请参阅 Array and JSON Casting。
现在您可以将数据作为 PHP 数组保存到属性中,并为其分配一个 PHP 数组。
$paste = Paste::first();
dump($paste); // Returns a PHP array
$paste->data = ['some-data' => 20, 'score' => 500];
$paste->save();
在内部,当它保存数据时,它会自动将其转换为 JSON 字符串并以正确的格式保存在数据库中。
存储方法
将输入作为 JSON 时,这在很大程度上取决于您希望如何传递数据,
1.发送内容类型为 JSON 的表单数据(推荐)
我的建议是在 POST 正文中将整个数据作为 JSON 发送,如下所示:
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!"
存储方法现在如下所示:
$this->validate($request, [
'data' => ['required', 'json'], // I'm unsure if data is required
]);
$data = json_decode($request->post('data'), true, JSON_THROW_ON_ERROR); // 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);
}
- 使用
->json()
作为存储JSON数据的迁移方法(https://laravel.com/docs/8.x/migrations#column-method-json)
- 请参阅“Array & JSON Casting”(https://laravel.com/docs/8.x/eloquent-mutators#array-and-json-casting)了解如何准备数据
我知道答案不像其他人那样在段落中,但我喜欢简单明了。这是最好的解决方案吗?没有人能告诉你,也没有人能证明这一点?这种方法行得通吗,没有人能告诉你也不能证明,但至少它提高了你的成功率。如果还有什么我可以帮忙的,请告诉我!祝你好运
只需将此添加到您的模型中即可。
protected $casts = [
'data' => 'object'
];
那么你可以这样进入你的视野:
{{ $data->data->name }}
我正在尝试将 json 存储到数据库中并将其加载回来
我尝试存储
{name: "John", age: 31, city: "New York"}
它存储正确。我检查了数据库,它显示正确。
{name: "John", age: 31, city: "New York"}
我一直在看
"{name: \"John\", age: 31, city: \"New York\"}"
这是我的代码。
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());
}
在我看来,我只有这一行
{!!$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));
}
结果
"{name: \"John\", age: 31, city: \"New York\"}"
尝试 # 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
对于那些怀疑我的 data/content
的人我试过在 Pastebin 中粘贴同一行
清理完毕,可以看下面
如果你想在数据库上将数据存储为 json 并恢复它,只需执行以下操作(我一直使用这种方式):
1- 将您的数据添加到数组:
$data["name"] = "John";
$data["age"] = 31;
$data["city"] = "New York";
2- 对数组进行编码并将其添加到数据库中(您可以将其存储为文本)
$encodedData = json_encode($data);
3- 如果您想添加嵌套 json 数据,只需将您的数组设为嵌套数组即可。
4- 恢复数据时只需使用 json_decode 对其进行解码
1- 您的列必须是 json 类型
$table->json('data');
2- 在您的模型中,您需要将列转换为数组
protected $casts = ['data' => 'array'];
3- 向您的控制器发送数据值必须是一个数组,以便您可以对其使用数组 Laravel 验证:
[
'data' => 'required|array',
'data.*.name' => 'required'
....
]
4- 当您存储数据时,它会被自动解析,同样当您检索数据列时,它会被转换为数组
数据库
在您的数据库迁移中添加:
$table->json('data'); // Recommended. Supported in MySQL since version 5.7.8
或
$table->text('data');
建议使用 JSON 列类型,因为它允许您对 JSON 数据执行 SQL 查询。参见 MySQL JSON Data Type
模型:投射属性
下一个问题是您需要能够将数据转换为 PHP 数组。
这是通过修改模型中的 casts 属性来完成的:
class Paste extends Model {
protected $casts = [
'data' => 'array'
];
}
有关详细信息,请参阅 Array and JSON Casting。
现在您可以将数据作为 PHP 数组保存到属性中,并为其分配一个 PHP 数组。
$paste = Paste::first();
dump($paste); // Returns a PHP array
$paste->data = ['some-data' => 20, 'score' => 500];
$paste->save();
在内部,当它保存数据时,它会自动将其转换为 JSON 字符串并以正确的格式保存在数据库中。
存储方法
将输入作为 JSON 时,这在很大程度上取决于您希望如何传递数据,
1.发送内容类型为 JSON 的表单数据(推荐)
我的建议是在 POST 正文中将整个数据作为 JSON 发送,如下所示:
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!"
存储方法现在如下所示:
$this->validate($request, [
'data' => ['required', 'json'], // I'm unsure if data is required
]);
$data = json_decode($request->post('data'), true, JSON_THROW_ON_ERROR); // 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);
}
- 使用
->json()
作为存储JSON数据的迁移方法(https://laravel.com/docs/8.x/migrations#column-method-json) - 请参阅“Array & JSON Casting”(https://laravel.com/docs/8.x/eloquent-mutators#array-and-json-casting)了解如何准备数据
我知道答案不像其他人那样在段落中,但我喜欢简单明了。这是最好的解决方案吗?没有人能告诉你,也没有人能证明这一点?这种方法行得通吗,没有人能告诉你也不能证明,但至少它提高了你的成功率。如果还有什么我可以帮忙的,请告诉我!祝你好运
只需将此添加到您的模型中即可。
protected $casts = [
'data' => 'object'
];
那么你可以这样进入你的视野:
{{ $data->data->name }}