PHP字符串转JSON如何转科学计数法_PHP字符串转JSON科学计数法处理方法
在PHP开发中,我们经常会遇到需要将字符串转换为JSON格式的场景。但当字符串中的数值较大或者较小的时候,转换为JSON后可能会出现科学计数法的形式,这往往不符合我们的业务预期,比如订单号、身份证号这类长数字字符串,如果转成科学计数法就会导致数据失真。本文将详细介绍PHP中处理字符串转JSON时出现科学计数法问题的几种有效方法。
问题复现
首先我们来看一个常见的场景,当字符串中包含长数字时,使用json_encode转换后可能出现科学计数法的情况。下面的代码可以复现这个问题:
<?php // 定义一个包含长数字的字符串 $str = "1234567890123456789"; // 尝试将字符串转为JSON $json = json_encode($str); // 输出结果 echo $json; // 部分PHP版本下输出可能是 "1.2345678901235e+18" ?>
这里的问题本质是json_encode在处理数值类型的时候,如果数值超出了PHP整型的范围,或者字符串中的数字被识别为数值类型,就可能会转换为科学计数法的形式输出。
方法一:强制指定为字符串类型
最基础的处理方式是在转换前明确告诉PHP这个值是字符串类型,避免被识别为数值。可以通过在变量前加字符串类型声明,或者在组装数组的时候手动给数值加上引号来实现。
<?php
// 方法1:直接定义字符串变量
$numStr = "1234567890123456789";
$data = [
"order_id" => $numStr
];
$json = json_encode($data);
echo $json;
// 输出:{"order_id":"1234567890123456789"}
// 方法2:对数值做字符串转换
$num = 1234567890123456789;
$data2 = [
"order_id" => (string)$num
];
$json2 = json_encode($data2);
echo $json2;
// 输出:{"order_id":"1234567890123456789"}
?>这种方式适合数据来源明确,我们能够提前控制变量类型的场景,简单直接,不需要额外的配置。
方法二:使用JSON_NUMERIC_CHECK选项的注意事项
很多开发者会使用JSON_NUMERIC_CHECK选项来让JSON中的字符串数值自动转为数字类型,但这个选项是导致科学计数法的常见原因,需要谨慎使用。
<?php $numStr = "1234567890123456789"; // 错误用法:使用JSON_NUMERIC_CHECK会导致长数字被转为科学计数法 $jsonWrong = json_encode($numStr, JSON_NUMERIC_CHECK); echo $jsonWrong . PHP_EOL; // 可能输出:1.2345678901235e+18 // 正确用法:不需要数字类型的时候不要加这个选项 $jsonRight = json_encode($numStr); echo $jsonRight . PHP_EOL; // 输出:"1234567890123456789" ?>
如果你的业务场景中确实需要将部分字符串转为数字,而其他长数字需要保留字符串形式,那么建议不要全局使用JSON_NUMERIC_CHECK,而是按需对单个字段做类型转换。
方法三:自定义处理长数字字符串
如果数据是从接口或者数据库中批量获取的,无法提前手动转换每个字段,可以写一个通用的处理函数,遍历数据中的长数字字符串,统一转为字符串类型,避免科学计数法问题。
<?php
/**
* 递归处理数组中的长数字字符串,避免JSON转换出现科学计数法
* @param mixed $data 需要处理的数据
* @return mixed 处理后的数据
*/
function handleLongNumberString($data) {
if (is_array($data)) {
foreach ($data as $key => $value) {
$data[$key] = handleLongNumberString($value);
}
return $data;
}
// 判断是否为纯数字字符串,且长度超过15位(一般15位以上容易出现科学计数法)
if (is_string($data) && preg_match('/^\d{15,}$/', $data)) {
return (string)$data;
}
return $data;
}
// 测试批量数据
$testData = [
"order_id" => "1234567890123456789",
"user_id" => 123456,
"goods_list" => [
["goods_id" => "9876543210987654321", "price" => "29.9"]
]
];
$handledData = handleLongNumberString($testData);
$json = json_encode($handledData, JSON_UNESCAPED_UNICODE);
echo $json;
// 输出:{"order_id":"1234567890123456789","user_id":123456,"goods_list":[{"goods_id":"9876543210987654321","price":"29.9"}]}
?>这个处理函数支持递归处理多维数组,会自动识别长度超过15位的纯数字字符串,将其强制转为字符串类型,既保留了普通数字的正常转换,又避免了长数字出现科学计数法的问题。
方法四:使用JSON_PARTIAL_OUTPUT_ON_ERROR选项(PHP 7.3+)
PHP 7.3及以上版本提供了JSON_PARTIAL_OUTPUT_ON_ERROR选项,当转换过程中出现错误时,会返回部分结果而不是报错,但这个选项不能从根源上解决科学计数法问题,只能作为兜底方案使用。
<?php
$longNum = "1234567890123456789";
// PHP 7.3+ 可以使用该选项,但本质还是需要处理类型
if (defined('JSON_PARTIAL_OUTPUT_ON_ERROR')) {
$json = json_encode($longNum, JSON_PARTIAL_OUTPUT_ON_ERROR);
echo $json;
}
?>需要注意的是,这个选项只是避免转换报错,如果你的长数字仍然被识别为数值类型,还是会出现科学计数法,所以不建议单独使用,最好配合类型强制转换一起使用。
总结
处理PHP字符串转JSON出现科学计数法的核心思路是:避免让长数字被识别为数值类型,从源头上保证其作为字符串参与JSON转换。实际开发中可以根据自己的场景选择合适的方法:
- 少量固定数据:直接定义字符串变量或者做强制类型转换即可
- 批量动态数据:使用递归处理函数统一处理长数字字符串
- 谨慎使用
JSON_NUMERIC_CHECK选项,避免不必要的数值转换
按照上述方法处理之后,就可以保证转换后的JSON中长数字字符串不会出现科学计数法,满足业务对数据准确性的要求。