Laravel 7更新多条过滤器名称时出现Illegal offset type错误如何解决
错误原因
- 第一个
Illegal offset type错误根源是遍历语法错误:你写的foreach ($item as $key)默认是将数组的值赋值给$key,此时$key是子过滤器数组本身,用数组作为数组下标自然属于非法偏移类型。 - 只更新第一条的问题:你使用路由注入的单个
Filter实例调用update()方法,不管循环多少次都是在更新同一个ID对应的过滤器记录,自然只会生效一次。 - 额外冗余代码:
$filters = collect([$request->filters])属于多余操作,$request->filters本身就是你提交的过滤器数组,额外套一层数组转集合反而平白多了一层嵌套,增加遍历复杂度。
批量更新实现方案
你提交的$item里的键(比如调试输出里的5、6)就是对应要更新的过滤器ID,直接按ID匹配更新即可,常规场景下的修正代码如下:
public function update(Request $request) { // 直接遍历提交的过滤器数组 foreach ($request->filters as $filterId => $filterData) { // 按ID查找对应记录再更新 Filter::where('id', $filterId)->update([ 'category_id' => $request->category_id, 'name' => $filterData['name'], 'latin' => $filterData['latin'], 'field' => $filterData['field'], ]); } // 后续返回逻辑自行补充 return back()->with('success', '批量更新成功'); }
如果需要更新的数据量较大,可以使用批量更新语法减少SQL查询次数,提升性能:
public function update(Request $request) { $filterIds = array_keys($request->filters); $categoryId = $request->input('category_id'); $cases = $casesLatin = $casesField = []; foreach ($request->filters as $filterId => $filterData) { $name = addslashes($filterData['name']); $latin = addslashes($filterData['latin']); $field = intval($filterData['field']); $cases[] = "WHEN id = {$filterId} THEN '{$name}'"; $casesLatin[] = "WHEN id = {$filterId} THEN '{$latin}'"; $casesField[] = "WHEN id = {$filterId} THEN '{$field}'"; } $ids = implode(',', $filterIds); \DB::statement("UPDATE filters SET category_id = $categoryId, name = CASE id ".implode(' ', $cases)." END, latin = CASE id ".implode(' ', $casesLatin)." END, field = CASE id ".implode(' ', $casesField)." END WHERE id IN ($ids)"); return back()->with('success', '批量更新成功'); }
注意:原生SQL批量更新方案需要做好参数转义,避免SQL注入风险,数据量较小的场景下直接按ID单条更新更安全易维护。
内容的提问来源于stack exchange,提问作者user16994315
相关产品推荐
相关产品推荐

