PHP Laravel 按搜索词查询站点模型列表返回空值问题排查
问题核心原因
- 你的
searchSiteByName方法返回的是Illuminate\Database\Eloquent\Collection集合对象,不是PHP原生数组,你用is_array($sites)做判断永远返回false,所以代码直接命中elseif (is_object($sites))分支返回null,这就是接口返回为空的直接原因。 - 额外存在多处逻辑漏洞:
- 未预加载
study关联关系,会产生N+1性能问题,若站点关联的项目被删除还会抛出属性读取错误 - 未处理
name参数为空时的返回逻辑 - 集合对象就算查询结果为空也应该返回空集合而非
null,避免前端类型判断异常
- 未预加载
修复后的代码
先修改searchSiteByName方法预加载关联
private function searchSiteByName(string $name): Collection { return Site::query() ->with('study') // 预加载study关联,避免N+1查询 ->where('name', 'LIKE', "%$name%") ->orWhere('site_number', 'LIKE', "%$name%") ->get(); }
再修改接口方法的类型判断和逻辑
public function listForReportEvent(Request $request) { // name参数为空时直接返回空集合,避免后续类型混乱 if (!$request->filled('name')) { return collect(); } $sites = $this->searchSiteByName($request->query('name')); // 直接处理集合返回结果,不需要额外判断类型 return $sites->map(function (Site $site) { // 加空判断避免study不存在时报错,不需要可删除 $studyId = optional($site->study)->ref_study_id ?? '未关联项目'; return [ 'text' => $studyId . '-' . $site->site_number . ': ' . $site->name, 'value' => $site->id, ]; })->values(); // 重置数组键,避免前端接收为对象格式 }
额外说明
如果不需要兼容关联不存在的情况,也可以在查询时加->whereHas('study')过滤掉没有关联项目的站点,就不用在map里做判空处理了。
内容的提问来源于stack exchange,提问作者Riza Khan
相关产品推荐
相关产品推荐

