You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中setBindings结合LIKE语句无结果问题排查

问题分析与解决办法

首先给你吃个定心丸:你最开始的写法其实已经是安全的,完全不用担心SQL注入风险!Laravel的查询构建器会自动把你拼接的%'.$keywords.'%作为参数绑定到SQL语句中,而不是直接把变量拼进SQL里,所以注入问题根本不存在。

那为什么用setBindings的写法会返回零结果呢?原因很简单:你在where条件里写的%?%,这个?并没有被Laravel识别为参数占位符——它只是字符串里的一个普通字符而已。最终执行的SQL会变成:

SELECT page_translations.id FROM page_translations WHERE page_translations.title LIKE '%?%'

这里的?就是字面量,而不是你绑定的'e',自然找不到匹配的记录。

正确的参数绑定写法

如果你想手动用参数绑定的方式实现(其实没必要,但可以了解),应该把%和变量结合后作为绑定值,而不是把?放在%中间。有几种可行方式:

方式1:直接把%加到绑定变量中(和你最初的写法本质一致,更清晰)

$keywords = 'e';
$searchTerm = "%{$keywords}%";
$pages = DB::table('page_translations')
    ->select('page_translations.id')
    ->where('page_translations.title', 'LIKE', $searchTerm)
    ->get()
    ->toArray();

这种写法和你最开始的代码效果完全一样,而且同样安全。

方式2:使用setBindings的正确姿势

一定要用setBindings的话,得让占位符是独立的,再把包含%的字符串作为绑定值:

$keywords = 'e';
$pages = DB::table('page_translations')
    ->select('page_translations.id')
    ->where('page_translations.title', 'LIKE', '?') // 这里的?是独立的占位符
    ->setBindings(["%{$keywords}%"])
    ->get()
    ->toArray();

更常用的是直接在whereRaw里传递绑定数组:

$keywords = 'e';
$pages = DB::table('page_translations')
    ->select('page_translations.id')
    ->whereRaw('page_translations.title LIKE ?', ["%{$keywords}%"])
    ->get()
    ->toArray();

方式3:用Laravel自带的whereLike(Laravel 9及以上版本支持)

Laravel 9+提供了更简洁的whereLike方法,自动帮你处理LIKE查询的通配符:

$keywords = 'e';
$pages = DB::table('page_translations')
    ->select('page_translations.id')
    ->whereLike('page_translations.title', $keywords)
    ->get()
    ->toArray();

默认会给关键词两边加上%,如果需要自定义通配符位置,还能传第三个参数,比如->whereLike('title', $keywords, 'before')只会在前面加%。

总结

  • 你最初的写法已经安全,不需要额外用setBindings;
  • 用setBindings失效的核心原因是%?%里的?不是有效的占位符;
  • 推荐用最初的写法或者whereLike(版本支持的话),简洁又安全。

内容的提问来源于stack exchange,提问作者learningtech

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 14:27:35