Chris Barnhill
Chris Barnhill

Reputation: 2027

PHP json_encode encoding numbers as strings

I am having one problem with the PHP json_encode function. It encodes numbers as strings, e.g.

array('id' => 3)

becomes

"{ ["id": "3", ...)

When js encounters these values, it interprets them as strings and numeric operations fail on them. Does anyone know some way to prevent json_encode from encoding numbers as strings? Thank you!

Upvotes: 172

Views: 178341

Answers (18)

lisandro
lisandro

Reputation: 506

I have this problem in a curl sending json that required some fields to be integer and other fields string, but some of the values of the string fields were in fact numbers so JSON_NUMERIC_CHECK didn't worked because it converted everything that looked as a number to number. The solution I've found was to add characters representing future double quotes, in my case I've used @ as I knew it was impossible to have this character in my data, to the fields representing string values

$analysis = array(

'SampleAnalysisId'  => $record[3],
'DisplayValue' => '@'.$record[4].'@',
'MeasurementUnit' => '@'.$record[5].'@',
'SampleAnalysisConclusionId'  => $record[6],
'Uncertaint' => '@'.$record[7].'@',
'K' => '',
'QuantificationLimit' => '@'.$record[8].'@',
'DetectionLimit' => '@'.$record[9].'@',
'Veff' => ''

);

Then after encoding I replaced the double quotes for empty and then replaced the '@' for double quotes.

$str = json_encode($analysis,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES );
$str = str_replace('@','"',str_replace('",',',',str_replace(':"',':',$str)));

Resulting in a formatted json according to my need

[{"SampleAnalysisId":10479,"DisplayValue":"6,3","MeasurementUnit":"mg/L","SampleAnalysisConclusionId":1,"Uncertaint":"0,194463","K":,"QuantificationLimit":"1","DetectionLimit":"0,30","Veff":"}]

Upvotes: 1

Rory Jarrard
Rory Jarrard

Reputation: 391

So Pascal MARTIN isn't getting enough credit here. Checking for numeric values on every JSON return is not feasable for an existing project with hundreds of server side functions.

I replaced php-mysql with php-mysqlnd, and the problem went away. Numbers are numbers, strings are strings, booleans are boolean.

Upvotes: 4

Rahul Gupta
Rahul Gupta

Reputation: 23

You can use (int) if any issue occurs!! It will work fine.

Upvotes: 1

Derrick Miller
Derrick Miller

Reputation: 1951

Casting the values to an int or float seems to fix it. For example:

$coordinates => array( 
    (float) $ap->latitude,
    (float) $ap->longitude 
);

Upvotes: 2

user5183775
user5183775

Reputation:

it is php version the problem, had the same issue upgraded my php version to 5.6 solved the problem

Upvotes: 2

Rijk
Rijk

Reputation: 11301

Note that since PHP 5.3.3, there's a flag for auto-converting numbers (the options parameter was added in PHP 5.3.0):

$arr = array( 'row_id' => '1', 'name' => 'George' );
echo json_encode( $arr, JSON_NUMERIC_CHECK ); // {"row_id":1,"name":"George"}

Upvotes: 407

Santini Arnaud
Santini Arnaud

Reputation: 19

Like oli_arborum said, I think you can use a preg_replace for doing the job. Just change the command like this :

$json = preg_replace('#:"(\d+)"#', ':$1', $json);

Upvotes: -3

mouckatron
mouckatron

Reputation: 1289

I, likewise was reading from a DB (PostgreSQL) and everything was a string. We loop over each row and do things with it to build up our final results array, so I used

$result_arr[] = array($db_row['name'], (int)$db_row['count']);

within the loop to force it to be an integer value. When I do json_encode($result_arr) now, it correctly formats it as a number. This allows you to control what is and is not a number coming from your database.

EDIT:

The json_encode() function also has the ability to do this on the fly using the JSON_NUMERIC_CHECK flag as a second argument to it. You need to be careful using it though as shown in this users example in the documentation (copied below): https://www.php.net/manual/en/function.json-encode.php#106641

<?php
// International phone number
json_encode(array('phone_number' => '+33123456789'), JSON_NUMERIC_CHECK);
?>

And then you get this JSON:

{"phone_number":33123456789}

Upvotes: 36

Leon
Leon

Reputation: 1863

Just run into the same problem and was the database returning the values as strings.

I use this as a workaround:

$a = array(
    'id' => $row['id'] * 1,
    'another' => ...,
    'ananother' => ...,
);
$json = json_encode($a);

That is multiplying the value by 1 to cast it into a number

Hope that helps someone

Upvotes: -1

Yar
Yar

Reputation: 4561

$rows = array();
while($r = mysql_fetch_assoc($result)) {
    $r["id"] = intval($r["id"]); 
    $rows[] = $r;
}
print json_encode($rows);  

Upvotes: 0

habibillah
habibillah

Reputation: 111

try $arr = array('var1' => 100, 'var2' => 200);
$json = json_encode( $arr, JSON_NUMERIC_CHECK);

But it just work on PHP 5.3.3. Look at this PHP json_encode change log http://php.net/manual/en/function.json-encode.php#refsect1-function.json-encode-changelog

Upvotes: 9

OzgurH
OzgurH

Reputation: 453

For sake of completeness (as I can't add comments yet), let me also add this detail as another answer:

(Edit: To be read after realizing that the source data (i.e. in the OP's case, database result set) could be the problem (by returning numeric columns as strings), and json_encode() in fact was not the source of the problem)

Manual pages of both "mysql_fetch_array":

Returns an array of strings that corresponds to the fetched row,

... and "mysql_ fetch_ row":

Returns an numerical array of strings that corresponds to the fetched row

clearly states that; the entries in the returned array will be strings.

(I was using the DB class in phpBB2 (yes I know, it's obsolete!), and "sql_fetchrow()" method of that class uses "mysql_fetch_array()")

Not realizing that, I also ended up finding this question, and understanding the problem! :)

As Pascal Martin stated above in his follow-up comments, I believe a solution that takes care of the "incorrect type" problem at the source (i.e. by using the "mysql_field_type()" function and doing the casting right after fetch, (or other fetch methods like "object"?)) would be the better in general.

Upvotes: 2

balucio
balucio

Reputation: 124

I also had the same problem processing data from the database. Basically the problem is that the type in the array to convert in json, is recognized by PHP as a string and not as integer. In my case I made a query that returns data from a DB column counting row. The PDO driver does not recognize the column as int, but as strings. I solved by performing a cast as int in the affected column.

Upvotes: 0

Jay Andrew Allen
Jay Andrew Allen

Reputation: 39

The following test confirms that changing the type to string causes json_encode() to return a numeric as a JSON string (i.e., surrounded by double quotes). Use settype(arr["var"], "integer") or settype($arr["var"], "float") to fix it.

<?php

class testclass {
    public $foo = 1;
    public $bar = 2;
    public $baz = "Hello, world";
}

$testarr = array( 'foo' => 1, 'bar' => 2, 'baz' => 'Hello, world');

$json_obj_txt = json_encode(new testclass());
$json_arr_txt = json_encode($testarr);

echo "<p>Object encoding:</p><pre>" . $json_obj_txt . "</pre>";
echo "<p>Array encoding:</p><pre>" . $json_arr_txt . "</pre>";

// Both above return ints as ints. Type the int to a string, though, and...
settype($testarr["foo"], "string");
$json_arr_cast_txt = json_encode($testarr);
echo "<p>Array encoding w/ cast:</p><pre>" . $json_arr_cast_txt . "</pre>";

?>

Upvotes: 3

oli_arborum
oli_arborum

Reputation: 398

I'm encountering the same problem (PHP-5.2.11/Windows). I'm using this workaround

$json = preg_replace( "/\"(\d+)\"/", '$1', $json );

which replaces all (non-negative, integer) numbers enclosed in quotes with the number itself ('"42"' becomes '42').

See also this comment in PHP manual.

Upvotes: 7

Pascal MARTIN
Pascal MARTIN

Reputation: 401182

I've done a very quick test :

$a = array(
    'id' => 152,
    'another' => 'test',
    'ananother' => 456,
);
$json = json_encode($a);
echo $json;

This seems to be like what you describe, if I'm not mistaken ?

And I'm getting as output :

{"id":152,"another":"test","ananother":456}

So, in this case, the integers have not been converted to string.


Still, this might be dependant of the version of PHP we are using : there have been a couple of json_encode related bugs corrected, depending on the version of PHP...

This test has been made with PHP 5.2.6 ; I'm getting the same thing with PHP 5.2.9 and 5.3.0 ; I don't have another 5.2.x version to test with, though :-(

Which version of PHP are you using ? Or is your test-case more complex than the example you posted ?

Maybe one bug report on http://bugs.php.net/ could be related ? For instance, Bug #40503 : json_encode integer conversion is inconsistent with PHP ?


Maybe Bug #38680 could interest you too, btw ?

Upvotes: 32

Richard Knop
Richard Knop

Reputation: 83755

Well, PHP json_encode() returns a string.

You can use parseFloat() or parseInt() in the js code though:

parseFloat('122.5'); // returns 122.5
parseInt('22'); // returns 22
parseInt('22.5'); // returns 22

Upvotes: -3

rogeriopvl
rogeriopvl

Reputation: 54154

json_encode serializes some data structure in JSON format to be send across the network. Therefore all content will be of the type string. Just like when you receive some parameter from $_POST or $_GET.

If you have to make numeric operations on the values sent, just convert them to int first (with the intval() function in PHP or parseInt() in Javascript) and then execute the operations.

Upvotes: -3

Related Questions