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

Fixing Warning: date_default_timezone_get(): It is not safe to rely on the system's timezone settings on Mac

If you run the following command:

php -i | grep 'Configuration File'

you will receive:

Loaded Configuration File => (none)

This is causing error of unspecified timezone or error:

Warning: date_default_timezone_get(): It is not safe to rely on the system’s timezone settings. You are required to use the date.timezone setting or the date_default_timezone_set() function.

To fix it, simply copy the php.ini.default in /etc

cp /etc/php.ini.default /etc/php.ini

sudo vim /etc/php.ini

search for timezone you’ll find a commented line:

[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
;date.timezone =

Uncomment it and assign your timezone, example:

[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone = Europe/London