如何解决Laravel中Call to a member function only() on array报错
问题原因及解决方案
1. 子数组调用only()报错的问题
only()是Laravel Request类、集合类的专属方法,你直接访问$request->programmeData时返回的是普通PHP数组,没有该方法,因此会抛出错误。
目前最优的两种解决方式可按需选择:
- 方法一:通过Request直接嵌套提取子数组字段
$programmeData = $request->only('programmeData.programme_id', 'programmeData.programme_title')['programmeData'];
- 方法二:使用Laravel数组辅助函数
Arr::only()处理,需提前导入门面
use Illuminate\Support\Arr; $programmeData = Arr::only($request->programmeData, ['programme_id', 'programme_title']);
拿到处理后的字段后再传给fill()方法即可正常运行。
2. foreach循环更新异常的问题
你现有代码存在两个核心问题:
- 每次循环都重复执行SQL查询获取匹配的Course记录,性能极低的同时,若查询结果的顺序和数组顺序不一致,就会出现赋值错位,导致同个值存入多条记录
- 没有做下标存在性校验,若某下标对应的记录不存在会直接抛出数组越界错误
优化后的正确写法如下:
use Illuminate\Support\Arr; // 先一次性查询所有匹配的Course记录,按主键排序后存储 $courses = Course::where('application_id', $application->id)->orderBy('id')->get(); foreach ($request->programmeData['userProgrammes'] as $key => $programme) { // 校验对应下标的记录存在再更新,避免报错 if (isset($courses[$key])) { $courses[$key]->fill(Arr::only($programme, ['programme_id']))->save(); } }
如果你的userProgrammes数组中存储了对应Course的主键ID,更稳妥的方式是按主键匹配更新,彻底避免顺序错位问题:
foreach ($request->programmeData['userProgrammes'] as $programme) { Course::where('id', $programme['course_id']) ->where('application_id', $application->id) ->update(Arr::only($programme, ['programme_id'])); }
3. FormRequest子数组校验配置
你可以直接在FormRequest的rules()方法中按嵌套规则配置子数组校验,提前完成数据合法性校验:
public function rules() { return [ // 其他字段校验规则 'programmeData.programme_id' => 'required|integer|exists:programmes,id', 'programmeData.programme_title' => 'required|string|max:255', 'programmeData.userProgrammes.*.programme_id' => 'required|integer|exists:programmes,id', // 若使用按主键更新的方案,新增对应规则 'programmeData.userProgrammes.*.course_id' => 'required|integer|exists:courses,id', ]; }
内容的提问来源于stack exchange,提问作者jkstallard
相关产品推荐
相关产品推荐

