
php 使用 json_encode 输出 json 时,默认将所有数值字段(如整数、浮点数)以原始格式序列化,但若数据在 php 中实际为字符串(即使内容是数字),则会被加引号;启用 json_numeric_check 可强制将纯数字字符串转为数值类型,确保前端 json.parse 得到一致的 javascript 数字类型。
php 使用 json_encode 输出 json 时,默认将所有数值字段(如整数、浮点数)以原始格式序列化,但若数据在 php 中实际为字符串(即使内容是数字),则会被加引号;启用 json_numeric_check 可强制将纯数字字符串转为数值类型,确保前端 json.parse 得到一致的 javascript 数字类型。
在 Web 开发中,前后端通过 JSON 交换数据时,常遇到一个看似微妙却影响深远的问题:同一响应中部分字段被解析为 JavaScript 数字(如 Monat: 2),而另一些字段却被解析为字符串(如 Gas: "13750.607")。这并非 JSON.parse() 的“错误行为”,而是源于 PHP 端 json_encode() 对数据类型的处理逻辑。
问题本质:PHP 数据类型决定 JSON 序列化格式
JavaScript 的 JSON.parse() 完全遵循 JSON 规范:123 是数字字面量,"123" 是字符串字面量。因此,最终解析结果完全取决于 PHP 输出的原始 JSON 字符串中是否带引号。而 json_encode() 的行为取决于其输入变量在 PHP 中的实际类型:
- 若 $row['Monat'] 是整型(int),json_encode() 输出 2 → 前端解析为 number;
- 若 $row['Gas'] 是字符串(string),即使内容为 "13750.607",json_encode() 输出 "13750.607" → 前端解析为 string。
在你的代码中,CAST(AVG(...), DECIMAL(10,3)) 返回的是数据库中的定点数值,但经 db2_fetch_assoc() 获取后,在 PHP 中通常被映射为 字符串类型(DB2 驱动默认行为),而非 float 或 int。这就是为何 Monat(来自 MONTH() 函数,返回整数)保持为 int,而 Gas/Öl/Strom 被当作字符串处理的根本原因。
正确解决方案:使用 JSON_NUMERIC_CHECK
PHP 自 5.3.3 起提供了 JSON_NUMERIC_CHECK 标志,它会自动检测数组或对象中值为纯数字字符串(如 "123"、"45.67")的字段,并在 JSON 序列化时将其转换为不带引号的数字字面量:
// ✅ 修正后的 PHP 输出逻辑(关键修复)
$jsonArray = array();
while ($row = db2_fetch_assoc($dbReturn)) {
$jsonArray[] = $row; // 注意:原代码中 echo 在循环内且未追加,此处已修正逻辑
}
// 启用 JSON_NUMERIC_CHECK 强制数值化
echo json_encode($jsonArray, JSON_NUMERIC_CHECK);⚠️ 补充说明:你原始代码中存在两个关键缺陷:
- while 循环内重复 echo json_encode($jsonArray),但 $jsonArray 始终为空(未填充);
- 即使填充了,也应在循环结束后统一输出一次完整数组,而非逐行输出碎片 JSON。
验证与调试建议
- 在 PHP 端打印类型诊断:
var_dump(gettype($row['Monat']), gettype($row['Gas'])); // 查看真实类型
- 在前端检查解析后类型:
console.log(typeof parsedData[0].Monat); // "number" console.log(typeof parsedData[0].Gas); // "number"(启用 JSON_NUMERIC_CHECK 后)
替代方案与注意事项
-
手动类型转换(不推荐):
$row['Gas'] = (float)$row['Gas']; // 显式转 float,再 json_encode
缺点:需对每个字段单独处理,易遗漏且耦合业务逻辑。
避免 JSON_NUMERIC_CHECK 的场景:
当字符串内容含前导零(如 "007")、科学计数法("1e5")或超大整数(可能精度丢失)时,该标志可能导致非预期转换,此时应优先保证语义正确性,接受字符串形式并在 JS 端按需转换。
总结
JSON.parse() 本身无“选择性解析”行为——它只是忠实还原 JSON 文本的结构。所谓“有的数字没引号、有的有”,根源在于 PHP 输出的 JSON 字符串本身格式不同,而该差异由 PHP 变量类型及 json_encode() 选项共同决定。启用 JSON_NUMERIC_CHECK 是解决此类混合类型问题最简洁、健壮的方案,它让序列化层自动承担类型归一化职责,显著提升前后端数据契约的可靠性。










