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!
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"}
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}
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 ?
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
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.
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>";
?>
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.
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.
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.
$rows = array();
while($r = mysql_fetch_assoc($result)) {
$r["id"] = intval($r["id"]);
$rows[] = $r;
}
print json_encode($rows);
it is php version the problem, had the same issue upgraded my php version to 5.6 solved the problem
Casting the values to an int or float seems to fix it. For example:
$coordinates => array(
(float) $ap->latitude,
(float) $ap->longitude
);
You can use (int) if any issue occurs!! It will work fine.
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":"}]
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
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.
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
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);
I have used JSON objects before and they work perfectly but the JSON objects that I made before have been from a result of fetched MySQL entries. Now, I am trying to make my own JSON object through an array in PHP and it shows correctly in the database but I cannot access any of the values like before.
$chatArray = array(
array(
'chatusername' => 'Troy',
'chatuserid' => '123',
'chatmessage' => 'Hello World'
),
array(
'chatusername' => 'Nick',
'chatuserid' => '124',
'chatmessage' => 'Testing'
));
$inputArray = json_encode($chatArray);
That is what I input into my database and like I said it works good. Then I call for it in a separate .php and get this
{"chat":"[{\"chatuserid\": \"123\", \"chatmessage\": \"Hello World\", \"chatusername\": \"Troy\"}, {\"chatuserid\": \"124\", \"chatmessage\": \"Testing\", \"chatusername\": \"Nick\"}]"}
It throws the "chat" out front which is the column name in my database which I am not sure why.
When I trace it I can only seem to trace it by
var messageArray:Object = JSON.parse(event.target.data);
trace(messageArray.chat);
Any time I try to reference say messageArray.chat.chatusername it returns an error.
I'm sorry I know it is probably a simple solution but I have been searching and working at it for a few hours now.
Any help is much appreciated! Thank you!
From the PHP code that generates your JSON output:
$stmt = $conn->prepare("SELECT chat FROM markerinfo WHERE markerid='$chatid'");
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
echo json_encode($result);
Keep in mind that the chat column in your database contains a JSON-string.
This code is not decoding the JSON-string in your database, so $result will be an array containing a JSON-string as well:
$result = [
'chat' => '[{"chatusername":"Troy","chatuserid":"123","chatmessage":"Hello World"},{"chatusername":"Nick","chatuserid":"124","chatmessage":"Testing"}]'
];
By passing that array through json_encode(), you're double-encoding your JSON-string.
For your purposes, you can probably get away with:
echo $result['chat'];
But, if you want the chat column name to be included in your output, you will have to decode the stored JSON first:
$result['chat'] = json_decode($result['chat']);
echo json_encode($result);
Probably this is related to the php side when it encodes your array, it will escape it with slashes, and this confuses the JSON parsing in your JS side. Try to add the JSON_UNESCAPED_SLASHES option to your json_encode function like this:
$inputArray = json_encode($chatArray, JSON_UNESCAPED_SLASHES);
Check the json_encode function documentation for more details:
http://php.net/manual/en/function.json-encode.php
I can retun this with json/php
exit('[{"name":"signup","state":"1","message":"this is a message"}]');
but not this:
$_SESSION["message"] = 'link: here ';
exit('[{"name":"signup","state":"1","message":"'.$_SESSION['message'].'"}]');
how can correct it?
JSON uses double quotes to encapsulate strings, and you're simply concatenating in a string that contains unescaped double quotes which breaks the encoding.
To ensure that all of your data is encapsulated and encoded properly do something like:
$data = [
'name' => 'signup',
'state' => '1',
'message' => $_SESSION['message']
];
echo json_encode($data);
exit();
json_encode() handles escaping, encoding, conversions, and anything else necessary to produce properly-formatted JSON.
If you want this at easiest way , follow my steps.
Dont make JSON manually..
Use this:
Make an array first.
Than use json_encode . You will get your data. correctly.
I am building data for a status dashboard that uses Highcharts.js, and loading it with ajax, however when using json_encode my timestamps are getting quoted, which means Highcharts chokes on them.
The code is:
$responseData = array();
foreach ($monitors as $monitor => $data) {
foreach (array_reverse($data['responsetime']) as $responsetime) :
$responses[] = array(strtotime($responsetime['datetime'])*1000 => $responsetime["value"]);
endforeach;
$responseData[] = array('name' => $data['friendlyname'], 'data' => $responses);
}
$responseData = json_encode($responseData,JSON_NUMERIC_CHECK);
Using JSON_NUMERIC_CHECK prevents problems with the value, but the key (a timestamp) gets quoted still.
Example output:
[{"name":"Series 1","data":[{"1432933860":1622},{"1432935660":1458},{"1432937461":1388}]},{"name":"Series 2","data":[{"1432933860":1622},{"1432935660":1458},{"1432937461":1388}]}]
Desired output:
[{"name":"Series 1","data":[{1432933860:1622},{1432935660:1458},{1432937461:1388}]},{"name":"Series 2","data":[{1432933860:1622},{1432935660:1458},{1432937461:1388}]}]
What am I doing wrong? Are keys always quoted perhaps?? Any way around this?
http://json.org/
From Objects
An object structure is represented as a pair of curly brackets surrounding zero or more name/value pairs (or members). A name is a string.
and from Strings
A string begins and ends with quotation marks.
So I would say that according to the standard: yes, you should always quote the key. Maby you could try to escape that key in javascript? Store them in a value and remove all non-numeric characters?
Something like:
myJsonKey = myJsonKey.replace(/\D/g,'');
I am working with a project that is coded in php OOP. I have created a form that post back to itself and gets those values and puts them into a predefined array format. I say predefined because this is the way the previous coder has done it:
$plane->add(array('{"name":"Chris","age":"22"}','{"name":"Joyce","age":"45"}'));
So when I get my values from the $_POST array, I thought it would be simple, so I tried
$plane->add(array("{'name':$customerName,'age':$customerAge}"));
This is triggering an error though, it seems it's passing the actual name of the variable in as a string instead of it's value. So how do I pass those values in to that function. While we are on it, can someone explain what kind of array that is, I thought arrays were always $key=>value set, not $key:$value.
As other comments and answers have pointed out, the data is being serialized in a format known as JSON. I suggest reading up on json_encode() and json_decode()
To make your example work, you would have to do:
$data = array("name" => $customerName, "age" => $customerAge);
$plane->add(array(json_encode($data));
That looks like json:
http://sandbox.onlinephpfunctions.com/code/e1f358d408a53a8133d3d2e5876ef46876dff8c6
Code:
$array = json_decode('{"name":"Chris","age":"22"}');
print_r( $array );
And you can convert an array to json with:
$array = array("Customer" => "John");
$arrayJson = json_encode( $array);
So to put it in your context:
$array = array("Name"=>"Chris", "age" => 22);
$array2 = array("Name"=>"John", "age" => 26);
$plane->add(array( json_encode( $array),json_encode( $array2) );
It looks like it could be JSON, but might not be.
Be careful to quote everything like they have done, you didn't have any quotes around the name or age.
I've added the same sort of quotes, and used the backslashes so that PHP doesn't use them to end the string:
$plane->add(array("{\"name\":\"$customerName\",\"age\":\"$customerAge\"}"));
Be wary of user data, if $customerName and $customerAge come from POST data, you need to properly escape them using a well tested escaping function, not something you just hack together ;)
It looks like your array is an array of JSON encoded arrays. Try using:
$plane->add(array('{"name":"' . $nameVar . '","age":"' . $ageVar . '"}', ...));
If you use the following:
echo json_encode(array('name' => 'Me', 'age' => '75'), array('name' => 'You', 'age' => '30'));
You will get the following string:
[{"name":"Me","age":"75"},{"name":"You","age":"30"}]
I believe you are getting an error because what you are trying to pass to the function is not JSON while (It looks like ) the function expects an array json strings, Manually trying to write the string might not be a good idea as certain characters and type encode differently. Best to use json_encode to get you json string.
$plane->add(array(json_encode(array('name'=>$customerName,'age'=>$customerAge))));