json_encode producing unexpected float values in PHP 7.1

php elephant 7.1

So I ran into an issue today while debugging a json string which is being produced from serialising an object. The float values had more decimal points than the ones in the object.

For example, consider the following code:

<?php

class MyFloatClass implements \JsonSerializable
{

    /**
     * @var float
     */
    public $value1;

    /**
     * @var float
     */
    public $value2;

    /**
     * myFloatClass constructor.
     * @param float $value1
     * @param float $value2
     */
    public function __construct($value1, $value2)
    {
        $this->value1 = $value1;
        $this->value2 = $value2;
    }

    function jsonSerialize()
    {
        return [
            'value1' => $this->value1,
            'value2' => $this->value2,
        ];
    }
}

$myObject = new MyFloatClass(12.23, 43.99);

echo json_encode($myObject->jsonSerialize());

Running the code above in PHP 7 will give the following output:

{"value1":12.23,"value2":43.99}

If you run the code in PHP 7.1 and you have serialize_precision not equal to -1, it will give totally different output.
Example, consider the following setting:

<?php

ini_set('precision', 14);
ini_set('serialize_precision', 17);


class MyFloatClass implements \JsonSerializable
{

    /**
     * @var float
     */
    public $value1;

    /**
     * @var float
     */
    public $value2;

    /**
     * myFloatClass constructor.
     * @param float $value1
     * @param float $value2
     */
    public function __construct($value1, $value2)
    {
        $this->value1 = $value1;
        $this->value2 = $value2;
    }

    function jsonSerialize()
    {
        return [
            'value1' => $this->value1,
            'value2' => $this->value2,
        ];
    }
}

$myObject = new MyFloatClass(12.23, 43.99);

echo json_encode($myObject->jsonSerialize());

output will be:

{"value1":12.23,"value2":43.990000000000002}

So first thing to check when having PHP 7.1 in your prod environment or even development environment is to check that you have default values for:

precision => 14
serialize_precision => -1

You can check that using CLI by running the following command:

php -i | grep precise

More reading: PHP Wiki – Precise Float Value

Photo Credit PHP Elephant with Christmas Tree Bokeh

Total Views: 26 ,
  • Vip3r011

    thanx 🙂
    i totaly forgot about serialize_precision => -1