ahoi's avatar
Level 5

Guzzle: Float changes to string

Hello everybody,

I am trying to post some data using Guzzle like this:

<?php
$client  = $this->client;
$this->payload = ['product' => ['title' => 'footer', 'price' => 12.99]];

$options = [];

$options['headers'] = [
    'Accept'        => 'application/json',
];

if ($this->method === 'POST' && $this->payload) {
    $options['json'] = $this->payload;
}

$response = $client->request($this->method,
    'https://host.local', $options);
}

Well - this works fine, but unfortunately the float 12.99 is transmitted as string to host.local.

host.local runs a Laravel-API and unfortunately I really need to accept a full JSON object containing float instead of string.

 public function store(Request $request)
    {
        /*Validate request*/
        $request->validate([
            'data.product'                  => 'nullable|array',
            'data.product.title'            => 'required|string',
            'data.product.price'            => 'required|numeric',
        ]);
 
        $offer = Offer::create([
            'product' => $request->input('data.product'),
        ]);
    }

This is saving the JSON object with a string "12.99".

Anything I can do to:

  • Transmit the value as float
  • Use the Controller to handle the given value to transform them into the correct type?
0 likes
4 replies
deepu07's avatar

Save as string and when use convert string to float by using Laravel typecasting?

guybrush_threepwood's avatar
Level 33

Could you try adding the content type to the header to see if it makes any difference?

$options['headers'] = [
    'Accept' => 'application/json',
    'Content-Type' => 'application/json'
];

There's a known issue where floats with no decimals are converted to integer, but I could not found any reference to floats being converted to string: https://github.com/guzzle/guzzle/issues/2538

guybrush_threepwood's avatar

It's my understanding that Guzzle leverages json_encode, which should be able parse the float correctly. Can you try just dumping a json_encode() of the array to see if the problem resides in json_encode() or Guzzle?

$array = ['product' => ['title' => 'footer', 'price' => 12.99]];
dd(json_encode($array));
guybrush_threepwood's avatar

A comment from PHP's documentation:

flags JSON_NUMERIC_CHECK and JSON_PRESERVE_ZERO_FRACTION are broken in php 7+ —

json_encode((float)8.8) returns "8.8000000000000007", and json_encode((float)8.8, JSON_NUMERIC_CHECK) and > json_encode((float)8.8, JSON_PRESERVE_ZERO_FRACTION) return "8.8000000000000007" too.

the only way to fix this is setting "serialize_precision = -1" in php.ini

Please or to participate in this conversation.