PHP mysqli根据截取的游戏厂商关键词查询相似游戏数据失败问题排查
问题分析与修复方案
你的代码里藏了几个关键问题,导致明明数据库有数据却查不到,咱们一步步拆解解决:
1. SQL查询逻辑完全错了
你的title字段格式是「厂商名称 - 游戏名」,但你写的title = "'.$gamecompany.'"是在找完全等于厂商名称的记录——这相当于在找标题就是Rockstar的游戏,而实际所有记录都是Rockstar - XXX,肯定匹配不上!
正确的做法是用LIKE匹配以厂商名称开头的标题,比如Rockstar -%,通配符%表示后面可以接任意内容。
2. 截取的厂商名称带多余空格
从strstr截取的内容可能带有尾部空格(比如示例里的Rockstar - GTA V,截取后是Rockstar ,后面多了个空格),这会让LIKE匹配也失效,必须用trim()清理前后空格。
3. SQL注入风险+字符编码适配问题
直接把变量拼进SQL里不仅容易被攻击,阿拉伯语的特殊字符也可能导致查询异常,必须用mysqli的预处理语句来处理。
4. 数据库连接的编码设置写错了
你写了mysqli_set_charset($link, 'utf8mb4');,但变量$link根本没定义!应该用你创建的连接变量$connect。另外,你原来的mysqli_connect参数顺序也错了——正确顺序是(主机, 用户名, 密码, 数据库名),你之前把用户名和数据库名搞反了,这可能直接导致连接失败!
修正后的完整代码
<?php // 修正连接参数顺序(主机, 用户名, 密码, 数据库名) $connect = mysqli_connect("localhost", "dbuser", "dbpass", "dbname"); if (!$connect) { die("数据库连接失败: " . mysqli_connect_error()); } // 统一设置编码为utf8mb4,适配阿拉伯语等全Unicode字符 mysqli_set_charset($connect, 'utf8mb4'); // 截取厂商名称并清理前后空格 $gamecompany = trim(strstr($_smarty_tpl->tpl_vars['game']->value['title'], '-', true)); // 使用预处理语句,避免SQL注入,同时适配特殊字符 $query = 'SELECT * FROM games WHERE title LIKE ? ORDER BY game_id ASC LIMIT 50'; $stmt = mysqli_prepare($connect, $query); // 绑定参数:匹配以「厂商名称 -」开头的所有游戏 $searchPattern = $gamecompany . ' -%'; mysqli_stmt_bind_param($stmt, 's', $searchPattern); // 执行查询 mysqli_stmt_execute($stmt); // 获取结果集 $result = mysqli_stmt_get_result($stmt); $output = ''; if(mysqli_num_rows($result) > 0) { $output .= '<div class="list">'; while($row = mysqli_fetch_array($result)) { $output .= '<li class="game"><a href="/'.$row["game_id"].'/" target="_blank">'.$row["title"].'</a></li>'; } $output .= '</div>'; echo $output; } else { echo 'Nothing Found'; } // 清理资源 mysqli_stmt_close($stmt); mysqli_close($connect); ?>
额外要检查的点
- 确保你的
games表和title字段的编码是utf8mb4(不是utf8,utf8mb4支持完整的Unicode字符); - 页面HTML头部要加
<meta charset="UTF-8">,避免阿拉伯语显示乱码; - 可以先手动echo一下
$gamecompany和$searchPattern,确认截取的厂商名称是正确的。
内容的提问来源于stack exchange,提问作者Ahmad Karimi
相关产品推荐
相关产品推荐

