MySQL中JSON_OBJECT查询结果json_decode失效问题排查
看起来你遇到的问题是MySQL生成的嵌套JSON对象在PHP中用json_decode无法正常解析,我来帮你排查和解决这个问题。
首先,排查MySQL生成的JSON是否合法
第一步先确认MySQL返回的address字段是不是标准的JSON格式。你可以直接在MySQL客户端执行你的SQL语句,查看address列的输出:
SELECT u.first_name, u.last_name, u.age, u.phone, JSON_OBJECT( 'zip', a.zip, 'address', a.address, 'number', a.number, 'city', a.city, 'state', a.state ) as 'address' FROM tb_user u, tb_user_address a WHERE u.id_address = a.id;
比如正常的输出应该是类似:
first_name | last_name | age | phone | address -----------|-----------|-----|-------|------------------------------------------ John | Doe | 30 | 12345 | {"zip":"10001","address":"Main St","number":"123","city":"New York","state":"NY"}
把address列的内容复制出来,在浏览器控制台用JSON.parse('这里放address内容')测试,如果能正常解析,说明MySQL生成的JSON是没问题的,问题出在PHP的结果处理环节。
如果是PHP处理的问题,尝试这些解决方案
1. 检查PHP是否对JSON字符串做了双重转义
有时候PHP的配置或数据库扩展会自动转义字符串中的反斜杠,导致JSON字符串变成类似"{\"zip\":\"10001\",...}"(注意这里的反斜杠是转义后的),但如果变成"{\\"zip\\":\\"10001\\",...}"(双重转义),json_decode就会失败。
你可以在PHP中先打印出获取到的address字段值:
// 假设用mysqli获取结果 $result = mysqli_query($conn, $sql); while ($row = mysqli_fetch_assoc($result)) { var_dump($row['address']); // 查看原始字符串 $address = json_decode($row['address'], true); var_dump($address); // 查看解析结果 }
如果看到var_dump输出的字符串有多余的反斜杠,可以用stripslashes处理后再解析:
$address = json_decode(stripslashes($row['address']), true);
不过注意:如果你的PHP环境开启了magic_quotes_gpc(PHP7+已移除,旧版本可能存在),建议关闭这个配置,因为它会自动转义GET/POST/COOKIE的数据,导致不必要的转义。
2. 直接让MySQL生成完整的JSON数组(更推荐)
如果你的目标是得到一个包含所有用户的JSON数组,不如直接让MySQL用JSON_ARRAYAGG生成整个数组,这样PHP只需要解析一次整个结果,避免逐个处理字段的麻烦:
SELECT JSON_ARRAYAGG( JSON_OBJECT( 'first_name', u.first_name, 'last_name', u.last_name, 'age', u.age, 'phone', u.phone, 'address', JSON_OBJECT( 'zip', a.zip, 'address', a.address, 'number', a.number, 'city', a.city, 'state', a.state ) ) ) AS user_list FROM tb_user u JOIN tb_user_address a ON u.id_address = a.id;
然后在PHP中获取user_list字段的值,直接解析:
$result = mysqli_query($conn, $sql); $row = mysqli_fetch_assoc($result); $users = json_decode($row['user_list'], true); var_dump($users); // 这就是你要的[{first_name: '...', address: {...}}]格式的数组
这种方法更可靠,因为MySQL直接生成完整的合法JSON,避免了PHP处理单个字段时的转义问题。
3. 检查地址字段是否有特殊字符
如果地址字段(比如a.address)包含引号、换行符等特殊字符,虽然MySQL的JSON_OBJECT会自动转义,但如果你的数据库字符集不是utf8mb4,可能会出现转义不完整的情况。确保你的表和连接都使用utf8mb4字符集,这样能正确处理所有Unicode字符。
总结
先确认MySQL生成的JSON是否合法,再排查PHP的转义问题,最推荐的方法是让MySQL直接生成完整的JSON数组,这样能减少后续处理的麻烦。
内容的提问来源于stack exchange,提问作者celsomtrindade

