如何在Yii中批量保存JSON POST请求中的多条注册数据至数据库
批量保存Bizzabo回调中的多条注册数据到数据库
你目前的代码只处理了details.items数组里的第一条数据,要实现批量保存所有注册信息,核心就是遍历这个items数组,为每一条数据创建独立的模型实例并完成保存。下面是修改后的完整代码及关键说明:
public function actionBizzaboCallback() { $junk = new Junk; $junk->code = 'bizzabo-bizzaboCallback-'.time(); $junk->content .= serialize($_POST); $successCount = 0; $failures = []; if ($_SERVER['REQUEST_METHOD'] == 'POST') { // 获取原始POST输入 $json = file_get_contents('php://input'); // 解析并验证JSON格式 $objects = json_decode($json); if (json_last_error() !== JSON_ERROR_NONE) { $junk = new Junk; $junk->code = 'bizzabo-getJSONError-'.time(); $junk->content = sprintf('JSON not captured at : %s', Yii::app()->params['masterDomain']); die(header('HTTP/1.0 415 Unsupported Media Type')); } else { // 提取公共事件信息,避免重复查询数据库 $eventCode = $objects->eventId; $tmps = HUB::getEventCode($eventCode); $eventId = $tmps->id; // 遍历所有注册条目,逐个处理保存 foreach ($objects->details->items as $item) { // 为每条注册数据创建新的模型实例 $object = new EventRegistration; $object->event_code = $eventCode; $object->event_id = $eventId; $object->event_vendor_code = 'bizzabo'; $object->registration_code = $item->ticketId; $object->full_name = sprintf('%s %s', $item->registrationForm->firstName, $item->registrationForm->lastName); $object->first_name = $item->registrationForm->firstName; $object->last_name = $item->registrationForm->lastName; $object->email = $item->registrationForm->email; $object->date_registered = time(); $object->date_payment = time(); $object->json_original = json_decode($json,true); // 若需单独存单条数据JSON,可改为json_encode($item) $object->date_added = time(); $object->date_modified = time(); // 保存并记录结果 if($object->save()){ $successCount++; }else{ $failures[] = [ 'email' => $item->registrationForm->email, 'errors' => $object->errors ]; } } // 整理日志内容,清晰展示批量处理结果 $successMsg = $successCount > 0 ? "成功保存{$successCount}条数据" : ''; $failMsg = !empty($failures) ? ",失败".count($failures)."条,详情:".json_encode($failures) : ''; $logContent = sprintf('%s%s。JSON原始数据:%s', $successMsg, $failMsg, $json); // 写入处理日志 $junk = new Junk; $junk->code = 'bizzabo-getBizzaboRegistrationIntoDB-'.time(); $junk->content = $logContent; } } $junk->save(); }
关键修改说明
- 遍历数组处理所有数据:用
foreach循环遍历items数组,替代原代码中仅取items[0]的逻辑,确保每条注册数据都被处理。 - 提取公共数据提升性能:将事件ID等所有注册数据共享的信息提到循环外,避免重复调用
HUB::getEventCode,减少不必要的数据库查询。 - 新增结果统计:用
successCount和failures变量记录批量操作的成功/失败情况,日志内容更直观,方便排查问题。 - 模型实例化调整:将
new EventRegistration放到循环内部,确保每条数据使用独立的模型实例,避免数据污染。
可选优化建议
- 如果希望每条记录仅保存自身的JSON数据(而非整个请求的JSON),可以把
$object->json_original = json_decode($json,true);改为$object->json_original = json_encode($item);。 - 对数据一致性要求高的场景,可以添加数据库事务:用
Yii::app()->db->beginTransaction()开启事务,循环保存后根据结果提交或回滚,避免部分数据保存成功、部分失败的情况。
内容的提问来源于stack exchange,提问作者rryys
相关产品推荐
相关产品推荐

