如何对多行查询结果进行JSON编码?多行结果编码失败求助
解决多结果集下json_encode失败的问题
兄弟,我瞅了下你的代码和问题,多结果集时json_encode失败、单行正常的情况,大概率是字符编码不兼容或者碰到了不可JSON序列化的内容,而且你的代码还有个隐藏的SQL注入坑,我给你一步步捋清楚哈:
核心问题分析
你循环构建数组的逻辑是没问题的,单行能正常输出就证明这点。多结果失败的常见原因:
- 数据库查询返回的字段包含非UTF-8编码的字符:json_encode只支持UTF-8编码的字符串,单行时刚好没碰到这类字符,多结果时触发了编码错误。
- 极少数情况是结果里有NULL或者特殊不可打印字符,不过这种概率较低。
解决方案
1. 先修复数据库连接编码
在你连接数据库的代码后面,加上强制设置编码的语句(用utf8mb4支持更全的字符,比如emoji):
mysqli_set_charset($db, "utf8mb4");
2. 给json_encode加上容错参数
直接在输出时添加编码处理参数,能自动处理大部分编码问题:
$json = json_encode($array, JSON_UNESCAPED_UNICODE | JSON_PARTIAL_OUTPUT_ON_ERROR); if ($json === false) { // 输出错误信息方便排查,线上环境可以改成返回空数组 echo json_encode(['error' => json_last_error_msg()]); } else { echo $json; }
JSON_PARTIAL_OUTPUT_ON_ERROR会在碰到无法序列化的内容时跳过它,而不是直接返回false,JSON_UNESCAPED_UNICODE能避免中文被转义成Unicode编码。
3. (可选)手动转码每个字段
如果上面的方法还不行,可以手动把每个字段转成UTF-8:
while ($row = mysqli_fetch_assoc($sql)) { // 自动检测原编码并转成UTF-8 $a = mb_convert_encoding($row['a'], 'UTF-8', mb_detect_encoding($row['a'])); $b = mb_convert_encoding($row['b'], 'UTF-8', mb_detect_encoding($row['b'])); $array[] = array( 'label' => $a . ', ' . $b, 'value' => $a, ); }
4. 必须修复的SQL注入风险!
你的代码直接把$_REQUEST['query']拼进SQL里,这是非常危险的,很容易被SQL注入攻击。改成预处理语句才安全:
if (isset($_REQUEST['query'])) { $query = $_REQUEST['query']; // 预处理SQL,用?作为占位符 $stmt = mysqli_prepare($db, "SELECT a, b FROM table WHERE a LIKE ? OR b LIKE ?"); // 拼接通配符,注意要在绑定参数前处理 $likePattern = "%{$query}%"; // 绑定两个字符串类型的参数(ss代表两个string) mysqli_stmt_bind_param($stmt, "ss", $likePattern, $likePattern); mysqli_stmt_execute($stmt); // 获取结果集 $result = mysqli_stmt_get_result($stmt); $array = array(); while ($row = mysqli_fetch_assoc($result)) { $array[] = array ( 'label' => $row['a'].', '.$row['b'], 'value' => $row['a'], ); } // 输出JSON $json = json_encode($array, JSON_UNESCAPED_UNICODE | JSON_PARTIAL_OUTPUT_ON_ERROR); echo $json ?: json_encode(['error' => json_last_error_msg()]); }
内容的提问来源于stack exchange,提问作者itranger
相关产品推荐
相关产品推荐

