PHP json_encode encoding numbers as strings

PhpJavascriptJson

Php Problem Overview


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!

Php Solutions


Solution 1 - Php

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"}

Solution 2 - Php

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): http://uk3.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}

Solution 3 - Php

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 ?

Solution 4 - Php

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

Solution 5 - Php

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.

Solution 6 - Php

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>";

?>

Solution 7 - Php

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.

Solution 8 - Php

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.

Solution 9 - Php

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.

Solution 10 - Php

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

Solution 11 - Php

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

Solution 12 - Php

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

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

Solution 13 - Php

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

Solution 14 - Php

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":"}]

Solution 15 - Php

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

Solution 16 - Php

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.

Solution 17 - Php

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

Solution 18 - Php

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);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionChris BarnhillView Question on Stackoverflow
Solution 1 - PhpRijkView Answer on Stackoverflow
Solution 2 - PhpmouckatronView Answer on Stackoverflow
Solution 3 - PhpPascal MARTINView Answer on Stackoverflow
Solution 4 - PhphabibillahView Answer on Stackoverflow
Solution 5 - Phpoli_arborumView Answer on Stackoverflow
Solution 6 - PhpJay Andrew AllenView Answer on Stackoverflow
Solution 7 - PhpRory JarrardView Answer on Stackoverflow
Solution 8 - PhpOzgurHView Answer on Stackoverflow
Solution 9 - PhpbalucioView Answer on Stackoverflow
Solution 10 - PhpYarView Answer on Stackoverflow
Solution 11 - PhpPeter AllenView Answer on Stackoverflow
Solution 12 - PhpDerrick MillerView Answer on Stackoverflow
Solution 13 - PhpRahul GuptaView Answer on Stackoverflow
Solution 14 - PhplisandroView Answer on Stackoverflow
Solution 15 - PhpLeonView Answer on Stackoverflow
Solution 16 - PhprogeriopvlView Answer on Stackoverflow
Solution 17 - PhpRichard KnopView Answer on Stackoverflow
Solution 18 - PhpSantini ArnaudView Answer on Stackoverflow