REST API向MySQL插入数据全为null问题排查(Swift SDK正常)
我开发了一个REST API,用于将JSON内容保存至MySQL数据库,但目前所有数据插入后均为null。奇怪的是,通过Swift SDK发送JSON时功能完全正常。相关代码如下:
public function saveTracking($request, $response, $args) { if(!$this->validToken($response)) { return $response; } $data = $request->getParsedBody(); $tracking_data = json_decode(json_encode($data['tracking']), FALSE); $total_records = 0; //error_log(print_r($tracking_data, true)); foreach($tracking_data as $key => $value) { $tracking = new EstablishmentTracking(); $tracking->mobile_user_id = $this->authUser->id; $tracking->report_date = $value->report_date; $tracking->establishment_id = $value->establishment_id; if ($value->platform == MobileUser::ANDROID || $value->platform == MobileUser::IOS) { $tracking->platform = $value->platform; } $tracking->purchase_id = $value->purchase_id; error_log(print_r($tracking, true)); $this->establishmentService->saveEstablishmentTracking($tracking); $total_records++; } $arr = array("status" => "ok" ,"total_records" => $total_records ); print_r($arr); $newResponse = $response->withJson($arr); return $newResponse; }
添加打印变量的代码后,得到以下输出:
stdClass Object ( [establishment_id] => 39 [report_date] => 2018-05-31 18:45:05 [platform] => android [purchase_id] => 0 )
请问是否是JSON未以数组形式正确发送?问题出在哪里?
从你给出的打印输出和代码细节来看,JSON发送的格式应该没问题(毕竟你能正确遍历$tracking_data并打印出属性值),问题大概率出在请求解析、模型赋值或者服务层保存逻辑上,我给你梳理几个排查方向:
1. 先确认请求头是否正确设置
你用的应该是Slim框架(从$request->getParsedBody()和响应方式判断),这个框架会根据请求的Content-Type头来解析请求体。如果Android端发送请求时没有设置Content-Type: application/json,哪怕你发的是JSON字符串,getParsedBody()可能也无法正确解析成你需要的结构——虽然你现在打印$tracking_data有值,但不排除解析过程中出现了隐性的类型问题,导致后续赋值模型时数据丢失。
建议让Android端检查请求头,确保带上正确的Content-Type。
2. 检查EstablishmentTracking模型的字段权限
看你的代码是直接给模型属性赋值,如果你用的是Eloquent这类ORM,要注意:
- 模型的
$fillable数组是否包含了mobile_user_id、report_date、establishment_id这些需要赋值的字段?虽然你不是用fill()或create()批量赋值,但部分ORM的严格模式下,未加入$fillable的字段可能会被忽略。 - 有没有设置
$guarded属性阻止了这些字段的赋值?如果$guarded不是空数组,要确认里面没有包含这些字段。 - 另外,检查模型的属性是否是公共可访问的,或者有没有定义对应的getter/setter导致赋值失败。
3. 调试模型赋值后的实际状态
你现在打印的是$tracking对象,但有些ORM会在内部维护属性的状态。建议在error_log(print_r($tracking, true));后面加一行代码,打印模型的原始属性(以Eloquent为例):
error_log(print_r($tracking->getAttributes(), true));
看看这里输出的属性值是不是正确的。如果这里已经变成null,说明赋值过程有问题;如果这里值是对的,那问题肯定出在saveEstablishmentTracking服务方法里。
4. 排查saveEstablishmentTracking方法的逻辑
打开你的服务类,检查这个方法是不是正确处理了传入的模型:
- 有没有重新给模型属性赋值覆盖了原来的正确值?
- 调用
save()方法前有没有做验证,导致验证失败却没抛出错误? - 有没有开启事务但没正确提交?
可以在这个方法里也添加日志,打印要保存的模型数据,确认保存前的值是否和你传入的一致。
5. 注意大小写匹配问题
看你打印的platform是小写的android,但代码里判断的是MobileUser::ANDROID——如果这个常量的值是大写的"ANDROID",那这个条件就不会成立,导致$tracking->platform没有被赋值。不过这只是单个字段的问题,其他字段也为null的话,这个不是主要原因,但还是要检查一下。
总的来说,Swift SDK能正常工作,说明API的核心逻辑是对的,重点排查Android端的请求头、模型的字段权限,以及服务层的保存逻辑。
内容的提问来源于stack exchange,提问作者Napify App

