PHP脚本中MySQL查询的西里尔文字符串被URL编码导致查询失效的问题
PHP脚本中MySQL查询的西里尔文字符串被URL编码导致查询失效的问题
嘿,这个问题我之前帮朋友排查过,咱们先搞清楚根源再一步步解决哈!
你看到的%d1%82%d0%b5%d1%81%d1%82+123其实是西里尔字符串тест123的URL编码结果,但MySQL的全文检索需要的是原始的UTF-8字符,它根本认不出这种百分号开头的编码格式,所以查询自然失效了。
给你几个具体的解决步骤:
先检查PHP代码里是不是不小心用了
urlencode()或者rawurlencode()函数处理了这个搜索字符串?如果有的话,直接删掉这个编码操作就行。比如之前写的是$search = urlencode('тест123');,改成$search = 'тест123';就搞定第一步了。如果已经拿到了编码后的字符串,没法回溯修改上游代码,那可以用
urldecode()函数把它转成原始字符串再传入查询:
$encoded_str = '%d1%82%d0%b5%d1%81%d1%82+123'; $decoded_str = urldecode($encoded_str); // 转换后得到"тест123"
- 还要确保你的数据库环境是UTF-8编码(推荐用
utf8mb4,支持更全的字符集),并且PHP和MySQL的连接也设置了对应的字符集,避免传输过程中乱码:
// 用PDO连接的话,直接在DSN里指定charset $pdo = new PDO('mysql:host=localhost;dbname=你的数据库名;charset=utf8mb4', '用户名', '密码'); // 用mysqli连接的话,额外设置字符集 $mysqli = mysqli_connect('localhost', '用户名', '密码', '你的数据库名'); mysqli_set_charset($mysqli, 'utf8mb4');
- 最后一定要用预处理语句执行查询,别直接把字符串拼进SQL里——既可以防止SQL注入,又能避免手动拼接时的编码坑:
// PDO预处理示例 $stmt = $pdo->prepare("SELECT text, MATCH(text) AGAINST (:search IN NATURAL LANGUAGE MODE) AS score FROM temp_text"); $stmt->bindParam(':search', $decoded_str); $stmt->execute(); $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
按照这些步骤处理后,MySQL就能正确识别你的西里尔字符串,全文检索也能正常返回结果啦!
备注:内容来源于stack exchange,提问作者lStoilov
相关产品推荐
相关产品推荐

