views:

1349

answers:

5

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!

A: 

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.

rogeriopvl
that's not what he's talking about. he's talking about the json having double quotes around the numbers.
JasonWoof
In the case of JSON, it does conserve Types. Imagine writing out a literal JavaScript Object, any quoted values become strings, but non-quoted numbers become integers, 0x[0-9a-z] becomes hex etc. There are type differences with PHP, such as, there is no such thing as an associative array, just Objects or indexed arrays etc.
bucabay
right. The problem he was having, was that he had a php variable, that he thought had type int, because it came from a DB column of type int. But in fact the PHP variable had type string, thus the quotes in the JSON.
JasonWoof
A: 

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
Richard Knop
Thanks. I was hoping there was a more elegant method.
Chris Barnhill
yeah, the safest way is to parse over them. but again, isn't Javascript loosely typed?
thephpdeveloper
+4  A: 

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 ?

Pascal MARTIN
Thanks Martin. I'm using 5.2.9. I wonder if the numeric data's getting read from the db as string? I'm sure the field types are int, but I can't think of another explanation. I'll try your quick test on my system and see if I get the same result.
Chris Barnhill
I got the same result as you. I wonder why PHP
Chris Barnhill
OK about 5.2.9 ; if your data is coming from a database, the problem might be there : I've often seen data come from database with everything casted to string (I've seen this with PDO and mssql ; but, if I remember correctly, this also happens for MySQL in PHP < 5.3, when the new mysqlnd driver was not yet existing) ;; to check what your data look like, you can use var_dump, which outputs the types of each part of the data.
Pascal MARTIN
(continued) thinks the data type for numeric values is string? Any ideas?
Chris Barnhill
MySQL is v14.12, dist 5.0.7
Chris Barnhill
I don't exactly know the technical reason of "why the data is returned from MySQL as a string" ;; probably something that has to do with the driver between PHP and MySQL ;; that is something that is (at least in some case) correcte by the new mysqlnd driver that comes with PHP 5.3 (see http://blog.ulf-wendel.de/?p=184 ; search for "integer" in the page to find the interesting sentence) ;; but I agree that this is not nice ^^
Pascal MARTIN
It doesn't matter that numeric data returned by json_encode() is not in quotes, it is still a string. The return value of the json_encode() function is a string. Regarding the MySQL returning all fields as strings, yes I have also encountered this specifically with PDO. The way I see it you should always cast values you expect to be numeric to integer (or float) in PHP to make sure, do not trust MySQL or any other database to return values with correct type.
Richard Knop
Yeah might just be Database returning as string. I've encountered problems like this before and what I did simply was to do casting on PHP.
thephpdeveloper
I think I found a way around this. I wrote this function for use with array_walk().function numStrToInt( }}
Chris Barnhill
I intend to use this function on every result set array I get back from MySQL query.
Chris Barnhill
@Chris : I suppose converting numerics to strings is a possibility, if you really need integers to be... well... integers ^^ ;; another nice solution would be to use a layer that maps values to their expected types -- but that would require a bit more work ^^
Pascal MARTIN
A: 

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.

oli_arborum
A: 

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

?>
Jay Andrew Allen