Laravel中数据库与API数据对比:快递商数据同步处理
嘿,我来帮你解决Laravel环境下RajaOngkir API快递商数据和数据库表的对比同步问题,结合你的场景给你具体的实现方案:
首先先明确你的基础数据:你已经通过以下代码拿到了API返回的所有快递商代码数组:
$cori = $rajaongkir->courier('all'); $cori = array_keys($cori); // 得到的数组是:["jne", "pos", "tiki", ..., "wahana"]
假设你的数据库表名为couriers(如果不是的话替换成你的实际表名),表中至少包含code(存储快递商代码,和API返回值对应)、name(快递商名称)、status(可选,标记是否有效)等字段,下面分场景处理:
1. 找出API有但数据库没有的快递商(批量新增)
先从数据库提取已存在的快递商代码,再和API数据对比找出需要新增的项,然后批量插入到数据库:
// 从数据库获取所有已存在的快递商code $dbCourierCodes = DB::table('couriers')->pluck('code')->toArray(); $apiCourierCodes = $cori; // 计算API有但数据库没有的快递商 $couriersToAdd = array_diff($apiCourierCodes, $dbCourierCodes); if (!empty($couriersToAdd)) { $newCouriers = []; foreach ($couriersToAdd as $code) { try { // 获取该快递商的完整信息(比如名称) $courierInfo = $rajaongkir->courier($code); $newCouriers[] = [ 'code' => $code, 'name' => $courierInfo[$code]['name'], 'status' => 'active', 'created_at' => now(), 'updated_at' => now() ]; } catch (\Exception $e) { // 捕获API请求异常,记录日志后跳过当前项 \Illuminate\Support\Facades\Log::error("获取快递商{$code}信息失败:{$e->getMessage()}"); continue; } } // 批量插入到数据库 DB::table('couriers')->insert($newCouriers); }
2. 找出数据库有但API没有的快递商(标记失效或删除)
如果某些快递商在API中已不存在,建议标记为失效而不是直接删除(避免数据丢失):
// 计算数据库有但API没有的快递商 $couriersToDisable = array_diff($dbCourierCodes, $apiCourierCodes); if (!empty($couriersToDisable)) { // 标记为失效状态 DB::table('couriers') ->whereIn('code', $couriersToDisable) ->update([ 'status' => 'inactive', 'updated_at' => now() ]); // 如果你确定要删除(谨慎操作),可以用下面的代码替代上面的update // DB::table('couriers')->whereIn('code', $couriersToDisable)->delete(); }
3. 同步数据库与API的快递商信息(比如名称更新)
如果API中快递商的名称有变更,可以同步更新数据库中的对应字段:
foreach ($apiCourierCodes as $code) { try { $courierInfo = $rajaongkir->courier($code); $dbCourier = DB::table('couriers')->where('code', $code)->first(); if ($dbCourier && $dbCourier->name !== $courierInfo[$code]['name']) { DB::table('couriers') ->where('code', $code) ->update([ 'name' => $courierInfo[$code]['name'], 'updated_at' => now() ]); } } catch (\Exception $e) { \Illuminate\Support\Facades\Log::error("同步快递商{$code}信息失败:{$e->getMessage()}"); continue; } }
优化建议
- 把这些逻辑封装成Artisan命令,比如
php artisan courier:sync,方便定时执行(可以用Laravel的任务调度每天自动同步一次) - 如果使用Eloquent模型(比如创建
App\Models\Courier),代码会更简洁,例如用Courier::pluck('code')->toArray()替代DB门面的写法 - 新增或更新时记得处理时间字段,Laravel的
now()方法会自动生成符合数据库格式的时间戳
内容的提问来源于stack exchange,提问作者mafortis
相关产品推荐
相关产品推荐

