I tried sending a POST request to the endpoint and received a 200 response, but the data I sent was incorrectly saved in the database;
I would like to know if the problem is with my post request or with the backend code that handles the request.
More specifically: I'm sending a POST request to the Laravel MariaDB backend. I didn't write the backend code, all the "details" I got were:
The post request has 3 fields:
- user_id: patient ID
- Password: patient password (same for all patients)
- payload: A json payload with the following structure:
- 'epoch_start' => 'Required|Number',
- 'epoch_end' => 'required|numeric|gte:epoch_start',
- 'Size' => 'Required|Number|gt:0',
- 'Temperature' => 'Required|Array|Minimum: size',
- 'Pressure' => 'Required|Array|Minimum: size',
- 'Move' => 'Required|Array|Minimum: size',
This is the controller that handles the request:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Validator; use Response; use App\Models\User; use App\Models\Sensor; use Carbon\Carbon; class SensorController extends Controller { public function storeData(Request $request) { if ($request->has(['user_id', 'password', 'payload'])) { $password = $request->get('password'); $user_id = $request->get('user_id'); $user = User::where('id', $user_id)->firstOrFail(); if($user->role != "patient") return new Response('Forbidden', 403); if($password != "HIDDENPASS") return new Response('Forbidden', 403); $payload = $request->get('payload'); $data = json_decode($payload, true); $rules = [ 'epoch_start' => 'required|numeric', 'epoch_end' => 'required|numeric|gte:epoch_start', 'size' => 'required|numeric|gt:0', 'temperature' => 'required|array|min:size', 'pressure' => 'required|array|min:size', 'movement' => 'required|array|min:size', 'temperature.*' => 'numeric', 'pressure.*' => 'numeric', 'movement.*' => 'numeric', ]; $validator = Validator::make($data, $rules); if ($validator->passes()) { $s = new Sensor; $s->user_id = $user->id; $s->epoch_start = Carbon::parse($data["epoch_start"]); $s->epoch_end = Carbon::parse($data["epoch_end"]); $s->size = $data["size"]; $s->temperature = json_encode($data["temperature"]); $s->pressure = json_encode($data["pressure"]); $s->movement = json_encode($data["movement"]); $s->save(); response()->json(['success' => 'success'], 200); } else { dd($validator->errors()); } } else { return new Response('Forbidden', 403); } } }
如果我使用 Postman 尝试此 Post 请求(我也尝试使用curl 和 python 的请求模块),我会收到 200 响应,并且数据以这种方式保存到数据库中。
问题出在“温度”、“压力”和“运动”字段上,更具体地说,是数组周围的双引号:由网络应用程序进行的涉及此数据的计算都是错误的,但是,如果我手动删除双引号(来自 PhpMyAdmin)计算是正确的。
为了完整起见,这里是表结构。
有没有办法避免这些字段周围出现双引号?
我的 POST 请求是否有问题,或者是后端相关的问题?
我不熟悉 PHP,但如果我没有记错的话,这些数据的处理应该由这些行管理:
$s->temperature = json_encode($data["temperature"]); $s->pressure = json_encode($data["pressure"]); $s->movement = json_encode($data["movement"]);
And json_encode returns a string, so I'm starting to think there's something wrong with the backend code here, but I'd like a second opinion.
Thanks in advance
Edit: Ok, thanks to @samuel-olufemi's answer and @sumit's comment, I can conclude that json_encode combined with the long text data type used by MariaDB is the main problem. So I tried to store the array values without encoding them, changed these 3 lines to:
$s->temperature = $data["temperature"]; $s->pressure = $data["pressure"]; $s->movement = $data["movement"];
And according to my wish, the data is stored without double quotes. Thanks for everyone's help and time.
P粉7941776592024-02-27 17:25:09
Your implementation is correct. The issue is caused by the way the Maria DB long text data type manages JSON data.
You can take a look at this answer