CodeIgniter Ajax请求MySQL LIKE查询字符串转字符问题
解决MySQL LIKE查询中字符串被截断为单个字符的问题
这种情况几乎都是直接拼接SQL语句导致的转义异常,还伴随严重的SQL注入风险!别担心,咱们一步步排查解决:
问题根源分析
你直接把$term拼进LIKE语句时,若字符串包含特殊字符(哪怕是看起来正常的字母),PHP的自动转义机制(比如旧版本的magic_quotes_gpc,或是你手动调用了addslashes())会给字符加转义符,导致MySQL解析时把'%Felix%'变成类似'%F\'elix%'的格式,最终破坏了LIKE的匹配逻辑,出现奇怪的字符截断。
而且直接把用户输入拼进SQL是非常危险的操作,攻击者可以轻松注入恶意代码篡改你的数据。
正确的解决方案:使用预处理语句
不管用PDO还是mysqli,都要用参数绑定的方式执行查询,这能彻底解决转义和注入问题。
方案1:PDO实现
// 假设已通过PDO连接数据库,$pdo为连接实例 $term = $_POST['term']; // 用占位符:term代替直接拼接字符串 $sql = "SELECT name, category FROM customers WHERE name LIKE CONCAT('%', :term, '%') OR phone LIKE CONCAT('%', :term, '%') OR customerId LIKE CONCAT('%', :term, '%')"; $stmt = $pdo->prepare($sql); // 绑定参数,指定参数类型为字符串 $stmt->bindParam(':term', $term, PDO::PARAM_STR); $stmt->execute(); // 获取查询结果 $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
方案2:mysqli实现(面向对象)
// 假设$conn为mysqli连接实例 $term = $_POST['term']; // 用?作为占位符 $sql = "SELECT name, category FROM customers WHERE name LIKE CONCAT('%', ?, '%') OR phone LIKE CONCAT('%', ?, '%') OR customerId LIKE CONCAT('%', ?, '%')"; $stmt = $conn->prepare($sql); // 绑定参数,"sss"表示三个字符串类型的参数 $stmt->bind_param("sss", $term, $term, $term); $stmt->execute(); // 获取结果集 $result = $stmt->get_result(); $results = $result->fetch_all(MYSQLI_ASSOC);
额外检查项
- 字符编码一致性:确保数据库连接字符编码和Ajax传递、页面输出的编码一致(推荐用
utf8mb4),可以在连接数据库后执行SET NAMES utf8mb4;,或是在PDO连接参数里指定charset=utf8mb4。 - 避免手动转义:不要给
$term调用addslashes()之类的转义函数,预处理语句会自动处理转义逻辑。
这样处理后,不仅能解决字符串被截断的问题,还能彻底杜绝SQL注入风险,是行业标准的安全做法。
内容的提问来源于stack exchange,提问作者Hassaan
相关产品推荐
相关产品推荐

