PHP返回JSON需确保字符集UTF-8、检查json_encode()返回值并记录错误、合理选用PDO/MySQLi及预处理语句。

PHP 从数据库查询数据并返回 JSON,核心就两点:查出来、转过去。但实际用的时候,90% 的问题出在编码、类型、错误处理这三块,不是语法不会,而是细节没兜住。
查完数据后直接 json_encode() 就行?别急,先看字符集
MySQL 默认连接可能用 latin1,而 PHP 脚本和前端通常期望 UTF-8。如果数据库字段存了中文,json_encode() 会直接返回 null 或空字符串——这是最常被忽略的静默失败。
- 连接 MySQL 后立刻执行
$pdo->exec("SET NAMES utf8mb4")(PDO)或mysqli_set_charset($conn, 'utf8mb4')(MySQLi) - 确保表和字段的字符集是
utf8mb4,不是utf8(后者不支持 emoji 和部分生僻字) - 输出前加
header('Content-Type: application/json; charset=utf-8'),避免浏览器或前端解析成乱码
json_encode() 返回 false 怎么快速定位?
它不报错,只默默返回 false。常见原因有:含不可序列化对象、资源类型(如 mysqli_result)、或存在循环引用。别靠猜,加一行检查:
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
$json = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PARTIAL_OUTPUT_ON_ERROR);
if ($json === false) {
error_log('JSON encode failed: ' . json_last_error_msg());
http_response_code(500);
echo json_encode(['error' => 'Invalid data']);
exit;
}
echo $json;
-
JSON_UNESCAPED_UNICODE防止中文被转成\uXXXX -
JSON_PARTIAL_OUTPUT_ON_ERROR让部分非法值(如 NaN、Infinity)被替换为空字符串,而非整个失败(仅 PHP 7.3+) - 永远用
json_last_error_msg()查具体哪条记录、哪个字段出问题
用 PDO 还是 MySQLi?选对方式影响调试效率
两者都能用,但默认行为差异会影响 JSON 输出稳定性:
立即学习“PHP免费学习笔记(深入)”;
- PDO 默认把数字字段当字符串返回(
PDO::ATTR_STRINGIFY_FETCHES = true),避免浮点数精度丢失;若需原生类型,设PDO::ATTR_EMULATE_PREPARES = false并配合PDO::ATTR_FETCH_TABLE_NAMES等精细控制 - MySQLi 的
fetch_all(MYSQLI_ASSOC)更直白,但遇到NULL字段时,若没显式设置mysqli_options($conn, MYSQLI_OPT_INT_AND_FLOAT_NATIVE, 1),整数可能被当字符串返回,导致前端typeof判断出错 - 无论哪种,都建议用预处理语句(
prepare/execute),防止 SQL 注入的同时也避免手动拼接字符串引入编码污染
真正卡住人的,往往不是“怎么返回 JSON”,而是“为什么前端收到的是空、null、乱码、或者少了一半数据”。字符集、错误抑制、类型隐式转换——这些点不一个个确认,光调 json_encode() 参数没用。











