Laravel Eloquent查询无结果但原生SQL有结果问题排查
问题原因及修复方案
核心问题1:参数绑定错误添加额外单引号
你在whereRaw和orWhere的like条件里,手动给搜索值加了单引号,但Laravel的参数绑定机制会自动为字符串参数添加单引号,导致最终生成的SQL里出现双层单引号(比如like ''%barcelona%''),这会让数据库无法匹配到正确结果。
核心问题2:Country条件存在变量错误与SQL注入风险
你判断$request->country不为空时,用whereRaw直接拼接$country变量,但代码里并未定义$country(应该是$request->country),同时直接拼接变量会带来SQL注入风险。
修复后的代码
$query = City::query(); $query->select('id', 'name as default_name', "translations->{$request['lang']} as name", 'country_id'); $query->where(function ($query) use ($request) { // 去掉手动添加的单引号,由Laravel自动处理参数绑定 $searchTerm = '%' . strtolower($request['search']) . '%'; $query->whereRaw('LOWER(translations->"$.' . $request["lang"] . '") like ?', [$searchTerm]); $query->orWhereRaw('LOWER(name) like ?', [$searchTerm]); }); if ($request->country !== null) { // 使用参数绑定避免SQL注入,同时修正变量名 $query->where('country_id', $request->country); } $results = $query->get();
修复说明
- 移除手动单引号:将搜索条件改为不带单引号的字符串,交给Laravel参数绑定自动处理引号,确保生成的SQL是
like '%barcelona%'而非like ''%barcelona%''。 - 修正Country变量:把未定义的
$country改为$request->country,同时使用where方法替代直接拼接,既避免SQL注入又符合Laravel规范。 - 统一小写处理:给
name字段也加上LOWER(),和前面的条件保持一致,确保搜索不区分大小写的逻辑统一。
内容的提问来源于stack exchange,提问作者Dioni Sánchez
相关产品推荐
相关产品推荐

