1

I have an issue when trying to decode JSON with the json_decode function in PHP 7.0.21. I am able to replicate this problem with these lines of code:

Code:

<?php
$inputJSON = '{"value":0.00000883}';
$outputJSON = json_decode($inputJSON);
print_r($outputJSON);

Output:

stdClass Object
(
    [value] => 8.83E-6
)

I also tried changing the precision with ini_set('precision', 8); which doesn't change the output.

The only fixes I found online were regex replaces which changed the number into a string but that's a hack and a good solution. I don't want to change ALL my float numbers to strings.

Why is this happening and how can I fix this properly without adding a lot of overhead like using number_format. Is the parsing simply broken in json_decode?

JohnMoe
  • 23
  • 3
  • 4
    That's the same number. `8.83E-6` is `8.83 * 10(^-6)`, which means go with the decimal point 6 times to the left. – FirstOne Nov 27 '17 at 11:29
  • 1
    What actual problem is this causing? Those formats are functionally identical in PHP. – iainn Nov 27 '17 at 11:29
  • That's called scientific notation. There are a bunch of dups out here, and here is one of them: [Why is PHP printing my number in scientific notation, when I specified it as .000021?](https://stackoverflow.com/questions/1471674/why-is-php-printing-my-number-in-scientific-notation-when-i-specified-it-as-00) – FirstOne Nov 27 '17 at 11:30
  • The thing is that I can't save the number like this in my database. It gives me an 'incorrect decimal value' error. But when I check the type in PHP it's just a float. Which is why I assumed that this is the problem. – JohnMoe Nov 27 '17 at 11:34
  • Maybe this? It fixed similar issues i had when encoding. Not sure about decoding. `ini_set( 'serialize_precision', -1 );` https://stackoverflow.com/questions/42981409/php7-1-json-encode-float-issue – Antony Thompson Nov 27 '17 at 11:36
  • 2
    That's just the result of casting a PHP float variable into string to be printed on screen (that's what `print_r()` accomplishes). If it's a problem in your DBMS, you must be using prepared statements incorrectly (or not using them at all). We need to see the relevant code. – Álvaro González Nov 27 '17 at 11:37
  • 1
    If your column requires that format then `number_format` is hardly a overhead. – Lawrence Cherone Nov 27 '17 at 11:38
  • @AntonyThompson Somehow this fixed my issue, I don't exactly understand what's going on and I suspect that it's my machine doing weird stuff somewhere. – JohnMoe Nov 27 '17 at 12:01

1 Answers1

3

You can use number_format to remove the e-6 so you can store correctly in your database;

<?php

$inputJSON = '{"value":0.00000883}';
$outputJSON = json_decode($inputJSON);

$formatted = number_format($outputJSON->value,8);

print_r($formatted);

outputs: 0.00000883

Although, I'm pretty sure MySQL should handle 8.83E-6 as an input.

IsThisJavascript
  • 1,726
  • 2
  • 16
  • 25
  • This is indeed what fixes the display error on my part, I tried to look for an explanation at the wrong place while it was a database issue. Setting the `ini_set('serialize_precision', -1);` somehow fixed my database insertion problem. – JohnMoe Nov 27 '17 at 12:04
  • In general terms this should just not be necessary. Not only do the major database engines I've tested (MySQL, SQL Server and Oracle) accept `8.83E-6` as number literal but whatever PHP database library you are using should handle numeric parameters just fine. – Álvaro González Nov 28 '17 at 08:08
  • What would be the solutions if $inputJSON has multiple values to be formatted and I am returning an array $outputJSON = json_decode($inputJSON, true); – alex Jan 01 '18 at 17:00
  • Hi @alex, you'll only want to run `number_format` on integers/longs/doubles and floats. So it would be `$formatted = number_format($outputJSON['TheArrayKey'],8);` where `TheArrayKey` is your array key for one of the above variable types. Since you have multiple to format, I would either make an object class for this or just loop through the results and reset the array. [Check out how to pass by reference](http://php.net/manual/en/language.references.pass.php) – IsThisJavascript Jan 03 '18 at 09:20