Coder Perfect

json encode() float issue in PHP7.1

Problem

This isn’t so much an inquiry as it is a warning. When I upgraded a PHP7.1.1 application that uses json encode(), I saw that floats were being altered to sometimes extend out to 17 digits. According to documentation, PHP 7.1.x started to use serialize_precision instead of precision when encoding double values. I’m guessing this caused an example value of

to become

After that, the value was encoded using json encode (). Since my discovery, I’ve gone back to PHP 7.0.16 and the json encode issue is no longer an issue (). Before reverting to PHP 7.0.16, I also attempted updating to PHP 7.1.2.

The reasoning behind this question does stem from PHP – Floating Number Precision, however the end all reason for this is because of the change from precision to serialize_precision usage in json_encode().

I’d be more than delighted to listen in on the reasoning/fix if anyone knows of a solution to this problem.

Excerpt from the previous multidimensional array:

[staticYaxisInfo] => Array
                    (
                        [17] => stdClass Object
                            (
                                [variable_id] => 17
                                [static] => 1
                                [min] => 0
                                [max] => 472.185
                                [locked_static] => 1
                            )

                    )

as well as after using json encode ()…

"staticYaxisInfo":
            {
                "17":
                {
                    "variable_id": "17",
                    "static": "1",
                    "min": 0,
                    "max": 472.18500000000006,
                    "locked_static": "1"
                }
            },

Asked by Gwi7d31

Solution #1

This drove me insane for a while until I discovered this bug, which directs you to this RFC.

And (emphasis mine)

In summary, there’s a new approach to force PHP 7.1’s json encode to use the new accuracy engine. You must change serialize precision to in php.ini.

serialize_precision = -1

This command line can be used to test if it works.

php -r '$price = ["price" => round("45.99", 2)]; echo json_encode($price);'

You should get

{"price":45.99}

Answered by Machavity

Solution #2

I don’t have general access to a server’s php.ini settings as a plugin developer. So, based on Machavity’s response, I created this short bit of code that you can incorporate into your PHP script. Simply place it on top of the script, and json encode will continue to function normally.

if (version_compare(phpversion(), '7.1', '>=')) {
    ini_set( 'serialize_precision', -1 );
}

In some circumstances, you’ll need to add another variable. I’m including this as a backup method because I’m not sure if the second option will work in all circumstances where the first has worked.

if (version_compare(phpversion(), '7.1', '>=')) {
    ini_set( 'precision', 17 );
    ini_set( 'serialize_precision', -1 );
}

Answered by alev

Solution #3

I addressed the problem by setting both precision and serialize precision to ten (10):

ini_set('precision', 10);
ini_set('serialize_precision', 10);

This can also be set in your php.ini file.

Answered by whatever_sa

Solution #4

I was encoding monetary values and had things like 330.4600000000000363797880709171295166015625 encoding to 330.4600000000000363797880709171295166015625 encoding. There is a really simple approach that works for me if you don’t want to, or can’t, change the PHP settings and you know the layout of the data ahead of time. Simply tie a string to it (both the following do the same thing)

$data['discount'] = (string) $data['discount'];
$data['discount'] = '' . $data['discount'];

a cost-effective and rapid solution Just keep in mind that because it’ll be encased in double quotes, it’ll be a string when decoded from JSON.

Answered by texelate

Solution #5

I had the similar issue, and just serialize precision = -1 did not solve it. I had to go through one more step to change the precision value from 14 to 17. (as it was set on my PHP7.0 ini file). Changing the value of the number, it appears, alters the value of the computed float.

Answered by Alin Pop

Post is based on https://stackoverflow.com/questions/42981409/php7-1-json-encode-float-issue