WordPress中LIKE查询为何需esc_like?不用会有严重风险吗?
WordPress中esc_like()的作用与不用它的风险
核心结论
不用$wpdb->esc_like()不仅会导致查询功能失效,还可能引发信息泄露或查询性能问题,不能仅依赖$wpdb->prepare()处理LIKE查询参数。
为什么$wpdb->prepare()不足以处理LIKE参数?
$wpdb->prepare()的核心作用是对字符串进行SQL注入防护,比如转义单引号、反斜杠等危险字符,但它不会处理LIKE语法特有的通配符:%(匹配任意长度字符)和_(匹配单个任意字符)。这些字符在SQL中是语法的一部分,而非普通文本,prepare()会直接保留它们的特殊含义,导致两个问题:
1. 查询功能失效
如果用户输入的内容包含%或_,直接用prepare()处理后,SQL会把它们当成通配符,而非字面意义的字符。比如:
- 用户输入:
only 43% of planets - 未用
esc_like()的代码:
生成的SQL会匹配所有包含$like = "%only 43% of planets%"; $sql = $wpdb->prepare("SELECT * FROM $wpdb->posts WHERE post_content LIKE %s", $like);only 43+ 任意内容 +of planets的帖子,而非精确匹配带43%的内容,完全偏离查询意图。
2. 潜在安全与性能风险
恶意用户可以利用未转义的通配符构造异常查询:
- 输入单个
%会让LIKE查询匹配所有记录,导致全表数据泄露; - 大量使用通配符(比如
%a%b%c%)会触发全表扫描,严重拖慢数据库性能; - 虽然不会直接引发传统SQL注入,但这种滥用会破坏查询的安全性和可用性。
esc_like()的作用是什么?
$wpdb->esc_like()专门用于转义LIKE查询中的特殊字符:
- 将
%转义为\% - 将
_转义为\_
转义后,这些字符会被SQL当作普通文本处理,同时搭配$wpdb->prepare()的注入防护,就能实现既安全又符合预期的LIKE查询。
正确用法示例:
$wild = '%'; $find = 'only 43% of planets'; // 先转义通配符,再拼接模糊匹配符号 $like = $wild . $wpdb->esc_like($find) . $wild; // 再用prepare做最终的SQL安全处理 $sql = $wpdb->prepare("SELECT * FROM $wpdb->posts WHERE post_content LIKE %s", $like);
总结
$wpdb->prepare()负责防SQL注入,但不处理LIKE通配符;esc_like()负责保证LIKE查询的逻辑正确性,避免通配符滥用;- 两者必须配合使用,才能兼顾查询的安全性和功能准确性。
内容的提问来源于stack exchange,提问作者Erasus
相关产品推荐
相关产品推荐

