Reputation: 47
I have this RAW JSON being returned and when I apply json_decode to access the data as an array it turns the trackingNumber into scientific notations. Is there any possible way to avoid this without compromising/rounding the integer or can I loop through the RAW JSON without decoding it? I've tried changing the precision and formatting it with number_format and both did work to an extent. However, there were some changes in the numbers around the middle of the integer as if it was rounded.
Original JSON data:
{
"data": {
"shipments": [
{
"packages": [
{
"responseDetails": {
"trackingNumber": 420217949361269903504794752430
}
}
]
}
]
}
}
When json_decode gets involved:
{
"data": {
"shipments": [
{
"packages": [
{
"responseDetails": {
"trackingNumber": 4.202179493612699e+29,
}
}
]
}
]
}
}
Changing precision:
<?php
ini_set('precision', 30);
$trackingNumber = 4.202179493612699e+29;
print $trackingNumber;
// Displays: 420217949361269887002807894016
?>
Using number_format():
<?php
$trackingNumber = number_format(4.202179493612699e+29, 0, '.', '');
print $trackingNumber;
// Displays: 420217949361269887002807894016
?>
Upvotes: 2
Views: 1982
Reputation: 8741
I would propose another solution if you use an older PHP then 5.4.0 within that JSON_BIGINT_AS_STRING is not defined. The idea is to handle trackingNumber as string, instead of bigInt. Any way, a tracking number can be an alphanumeric string in real life. If you cannot revise it manually, we shall convert it programatically. Following is a solution:
<?php
$strJSON = <<<EOF
{ "data": {
"shipments": [
{
"packages": [
{
"responseDetails": {
"trackingNumber": 420217949361269903504794752430
}
}
]
}
]
}
}
EOF;
//
// convert trackingnumber into string by double quoting the integer:
//
$strJSON = preg_replace('/"trackingNumber":\s*(\d+)/', '"trackingNumber": "$1"', $strJSON);
//
// here $strJSON is like this:
// ...
// "trackingNumber": "420217949361269903504794752430"
// ...
//
//echo "<pre>" . $strJSON . "</pre>";
//exit;
//
$objJSON = json_decode($strJSON);
//
echo "<pre>";
var_dump($objJSON);
echo "</pre>";
?>
The above code gives:
object(stdClass)#5 (1) {
["data"]=>
object(stdClass)#4 (1) {
["shipments"]=>
array(1) {
[0]=>
object(stdClass)#3 (1) {
["packages"]=>
array(1) {
[0]=>
object(stdClass)#2 (1) {
["responseDetails"]=>
object(stdClass)#1 (1) {
["trackingNumber"]=>
string(30) "420217949361269903504794752430"
}
}
}
}
}
}
}
Upvotes: 1
Reputation: 6169
This is because by default the big numbers are converted to float
which is hurting their precision.
The json_decode()
fourth param allows you to set options for decoding. You can use option JSON_BIGINT_AS_STRING
to force conversion to string
instead of float
. I guess that you don't need to do any calculations with the number so working with string should be fine.
The whole function call might look like this:
$result = json_decode($jsonString, false, 512, JSON_BIGINT_AS_STRING);
Upvotes: 3