Laravel中如何对比两个同记录对象并获取发生变更的字段
首先纠正你示例代码的逻辑问题:你在修改$before_update并调用save()方法后,该变量本身已经存储了更新后的值,此时再查询得到的$after_update和$before_update内容完全一致,无法做差异对比。
以下是两种可行的实现方案:
方案1:无需二次查询,直接用Laravel Eloquent内置方法获取变更字段
Eloquent模型本身自带修改记录能力,你可以在更新操作前后调用内置方法直接拿到变动内容,不需要额外查两次数据库:
$model = DeliveryRun::find($id); // 存储更新前的全部原始字段值 $originalValues = $model->getOriginal(); // 执行更新逻辑 $model->name = $request->input('name'); $model->save(); // 直接获取所有发生变更的字段+更新后的值 $changedInfo = $model->getChanges();
返回的$changedInfo是关联数组,键为变动的字段名,值为更新后的字段值。如果需要同时展示新旧值,遍历$changedInfo的键从$originalValues取值对应即可。
方案2:两个独立模型实例的对比方法
如果你确实已经拿到了两个独立的更新前后的模型实例(比如跨请求、跨事务获取的场景),可以用以下自定义方法做对比:
/** * 对比两个同表模型实例的字段差异 * @param $modelBefore 更新前的模型实例 * @param $modelAfter 更新后的模型实例 * @return array 差异字段数组,包含每个字段的新旧值 */ function compareModelDiff($modelBefore, $modelAfter): array { // 仅提取模型的业务字段值,排除模型内置属性 $beforeAttrs = $modelBefore->getAttributes(); $afterAttrs = $modelAfter->getAttributes(); $diffResult = []; foreach ($beforeAttrs as $field => $oldVal) { $newVal = $afterAttrs[$field] ?? null; // 用严格比较避免数字、字符串隐式转换导致的误判 if ($oldVal !== $newVal) { $diffResult[$field] = [ 'old_value' => $oldVal, 'new_value' => $newVal ]; } } return $diffResult; } // 调用示例 $changedFields = compareModelDiff($before_update, $after_update);
内容的提问来源于stack exchange,提问作者Bilal Arshad
相关产品推荐
相关产品推荐

