本文讲解如何安全、准确地将逗号分隔的关键词字符串拆分为数组,并动态构建支持多关键词模糊匹配的mysql查询语句,重点解决因空格未被识别导致的where条件失效问题。
在PHP中,将用户输入的关键词字符串(如 "paper, glue, discount, bulk")拆解为数组并用于构建动态SQL查询是常见需求。但一个极易被忽略的细节会导致整个查询逻辑失效:字符串分隔符未与实际格式严格匹配。
你当前的代码使用了:
$new_search = preg_split("/,/", $my_search);这会将 "paper, glue, discount, bulk" 拆分为:
['paper', ' glue', ' discount', ' bulk']
注意:每个后续元素开头都带有一个前导空格(' glue' 而非 'glue')。当拼接进 LIKE '%$value%' 时,实际生成的是 LIKE '% glue%' —— 数据库中几乎不可能存在以空格开头的关键词,因此该条件恒为 FALSE。而由于你初始条件是 LIKE '%offers%' OR ...,一旦 '%offers%' 在表中不存在(或字段值不含 "offers"),整个 OR 链因逻辑短路失效,最终可能退化为全表扫描(尤其当 WHERE 子句因语法/语义错误未能有效过滤时),表现为“返回所有行”。
✅ 正确做法是按 ,(逗号+空格) 精确分割:
$my_search = "paper, glue, discount, bulk";
$new_search = preg_split("/, /", $my_search); // 注意空格
// 结果:['paper', 'glue', 'discount', 'bulk']更健壮的写法(兼容多余空格、首尾空格):
$my_search = trim($my_search); // 去首尾空格
$new_search = array_map('trim', preg_split('/,\s*/', $my_search)); // 支持逗号后任意空白
$new_search = array_filter($new_search, 'strlen'); // 过滤空元素构建查询时,还需注意以下关键点:
? 避免SQL注入风险:直接拼接 $value 极其危险。应使用预处理语句或至少对关键词进行转义:
// 推荐:使用 PDO 预处理(更安全)
$placeholders = str_repeat('?,', count($new_search) - 1) . '?';
$sql = "SELECT * FROM clients_personal WHERE likes LIKE ? " .
str_repeat(" OR likes LIKE ? ", count($new_search) - 1);
$stmt = $pdo->prepare($sql);
$params = array_map(fn($v) => "%{$v}%", $new_search);
$stmt->execute($params);? 逻辑修正:你原始SQL以 WHERE likes LIKE '%offers%' OR ... 开头,但 'offers' 并不在 $new_search 中 —— 它是硬编码的额外条件。若本意是仅匹配用户输入的关键词,应从 WHERE 后直接开始拼接:
if (empty($new_search)) {
die("No keywords p
rovided");
}
$conditions = [];
$params = [];
foreach ($new_search as $value) {
$conditions[] = "likes LIKE ?";
$params[] = "%{$value}%";
}
$mmsql = "SELECT * FROM clients_personal WHERE " . implode(' OR ', $conditions);
$stmt = $conn->prepare($mmsql);
$stmt->execute($params);? 性能提醒:LIKE '%keyword%' 无法使用索引,大数据量下性能较差。如需高效搜索,建议考虑全文索引(FULLTEXT)或专用搜索引擎(如Elasticsearch)。
总结:字符串分割必须与原始格式一致;动态SQL务必防御注入;逻辑起点(WHERE 后首个条件)需清晰明确;生产环境优先采用预处理语句。
# mysql
# php
# word
# 编码
# 大数据
# sql注入
# 搜索引擎
# sql
# 字符串
# elasticsearch
# 数据库
# 关键词
# 的是
# 子句
# 不可能
# 它是
# 不含
# 而非
# 如需
# 表现为
# 首个
相关栏目:
【
Google疑问12 】
【
Facebook疑问10 】
【
网络优化76771 】
【
技术知识130152 】
【
IDC云计算60162 】
【
营销推广131313 】
【
AI优化88182 】
【
百度推广37138 】
【
网站推荐60173 】
【
精选阅读31334 】
相关推荐:
如何使用Golang包导出规则_控制函数和变量可见性
php本地部署支持nodejs吗_php与nodejs混合开发环境搭建教程【教程】
如何在 PHP 中按相同键合并两个关联数组为二维数组
如何在Windows中创建新的用户账户?(标准与管理员)
Win10怎样清理C盘爱奇艺缓存_Win10清理爱奇艺缓存步骤【步骤】
如何高效获取循环末次生成的 NumPy 数组最后一个元素(无需额外循环)
PHP接收参数值为空怎么办_判断和处理空参数方法说明【说明】
如何在 Go 同包不同文件中正确引用结构体
如何从 Go 的 map[string]interface{} 中安全获取值
如何自定义Windows终端的默认配置文件?(PowerShell/CMD)
php下载安装选zip还是msi格式_两种安装包对比【教程】
Win11相机打不开提示错误怎么修_相机权限开启与驱动修复【影像修复】
如何在 Python 中将 ISO 8601 时间戳转换为日期并计算日期差值
c++中explicit(bool)的用法 c++条件性explicit【C++20】
Win10如何卸载自带Edge_Win10彻底卸载Edge浏览器教程【攻略】
Win11怎么打开旧版计算器_Win11恢复传统计算器应用【详解】
c# 服务器GC和工作站GC的区别和设置
VSC怎么在PHP中调试MySQL_数据库交互排查技巧【教程】
php本地部署后数据库连接报错_1045accessdenied错误解决方法详解【汇总】
Mac的访达(Finder)怎么用_Mac文件管理入门教程【详解】
c++ stringstream用法详解_c++字符串与数字转换利器
php增删改查需要哪些扩展_开启mysqli或pdo扩展方法【说明】
Win11怎么更改鼠标指针方案_Windows11自定义鼠标光标样式与大小
PHP中require语句后直接调用返回对象方法的语法解析
php8.4匿名类怎么用_php8.4匿名类创建与使用场景【介绍】
Python技术债务管理_长期维护解析【教程】
php8.4如何实现队列任务_php8.4redis队列简单实现方法【教程】
php怎么下载安装后测试是否成功_简单脚本验证方法【操作】
Win10怎样清理C盘Steam游戏缓存_Win10清理Steam游戏缓存步骤【步骤】
c# await 一个已经完成的Task会发生什么
win11如何清理传递优化文件 Win11为C盘瘦身删除更新缓存【技巧】
如何使用Golang实现容器安全扫描_Golang Docker镜像漏洞检测方法
如何使用 Selenium 正确获取篮球参考网站球员名单元素列表
Win11怎么关闭自动调节亮度_Windows11禁用内容自适应亮度
Go语言中CookieJar的持久化机制解析:内存存储与自定义持久化方案
php内存溢出怎么排查_php内存限制调试与优化方法【说明】
c# Task.Yield 的作用是什么 它和Task.Delay(1)有区别吗
Drupal 中 HTML 链接被重复转义导致渲染异常的解决方案
用Python构建微服务架构实践_FastAPI与Django对比详解
PowerShell怎么创建复杂的XML结构
Win11如何更新显卡驱动 Win11检查和安装设备驱动程序【方法】
mac怎么分屏_MAC双屏显示与分屏操作技巧【指南】
c# F# 的 MailboxProcessor 和 C# 的 Actor 模型
如何使用Golang安装依赖库_管理模块和第三方包
Windows电脑键盘突然失灵怎么办?(驱动与硬件排查)
如何在 Go 应用中实现自动错误恢复与进程重启机制
c++怎么处理多线程死锁_c++ lock_guard与unique_lock锁管理【技巧】
Win11开机Logo怎么换_Win11自定义启动画面工具【高级】
Windows10如何更改桌面背景_Win10个性化幻灯片放映设置
c++获取当前时间戳_c++ time函数使用详解
2025-12-29
致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。