Prevent strtotime being encoded as string by json_encode - php

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

Related

How to display the values as numbers without quotes via PDO MYSQL? [duplicate]

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

Escaping slashes when decoding json php

I have a problem when returning a row from database that has a column type TEXT(in this case, column "details") which contains an array of JSON objects. Example:
{
productid: 1
shopid: 1
title: 'Product 1'
--> details: [{"name":"Brand name","value":"Brand value"},{"name":"Color","value":"blue"}]
. . .
}
Data inserted into database in columns of type TEXT are inserted like addslashes(json_encode($array_or_object)) to safely escape before insert.
When returning data, columns of type TEXT by function json_decode() and returned with no problem. Problem occurs when someone tries using single ' and double quotes " in details. Example:
details: [{"name":"\\\"test123\\\"","value":"\\\"test\\\" \\'test\\' \\\"test \\' test \\' t\\\"est"}]
Returned value looks like:
"details": [
{
"name": "\\\"test123\\\"",
"value": "\\\"test\\\" \\'test\\' \\\"test \\' test \\' t\\\"est"
}
],
I have more than one way of storing JSON data in database (as object, array of objects, array of arrays of objects,...), and I need a way to escape these backslashes.
Using stripslashes() on the string before using json_decode() does not work, it breaks the JSON.
Creating a recursive function works, but is not as pretty as I would like it to be. Example:
function decode_json($json) {
if (empty($json)) {
return $json;
}
if (is_string($json)) {
$json = json_decode($json, true);
}
foreach ($json as $key => $value) {
if (is_array($value)) {
$json[$key] = decode_json($value);
continue;
}
$json[$key] = stripslashes($value);
}
return $json;
}
Any help is appreciated.
json_encode already escape your string, you don't need to use addslashes()
Example:
$var = ["value" => "test'\""];
print_r(json_encode($var));
Result:
{"value":"test'\""}
And will be better to use PDO with bind parameters: https://www.php.net/manual/en/pdostatement.bindparam.php
and what exactly is the point of using a database, when storing the raw JSON?
decode first, then escape the values to insert - else you'll also escape all of the JSON delimiters,
which might subsequently cripple the whole input string and render it F.U.B.A.R.
PS: PDOStatement still requires PDO::quote() to escape the input properly.

How to remove quotes from numerical array value

How can I let my PHP server respond with some thing like this:
{"eCode":0,"city":"london","time":"15:35"}
not:
{"eCode":"0","city":"london","time":"15:35"}
I'm using this PHP code:
<?php
$data = array('eCode' => '0', 'city' => 'london', 'time' => '15:35');
header('Content-type: application/json');
echo json_encode($data);
?>
So how can I remove the quotes from "eCode":"0", and replace it with "eCode":0, ?
You're quoting the zero, making it a string. Just leave it as a int:
<?php
$data = array('eCode' => 0, 'city' => 'london', 'time' => '15:35');
echo json_encode($data);
?>
This answer reiterates some things that were already said by others, but hopefully a little more explanation will be helpful.
Basically, the zero is quoted in the output of json_encode($data) because it is quoted in the input.
json_encode will not automatically convert numeric strings to integers, unless you have set the JSON_NUMERIC_CHECK option, for example:
echo json_encode($data, JSON_NUMERIC_CHECK);
If you are constructing the array you're attempting to json_encode with your code, then you should be able to simply add ints rather than numeric strings into the array as you build it:
$data['eCode'] = 0; // use 0 instead of '0'
$data['city'] = 'london';
$data['time'] = '15:35';
However, if the array you're working with is coming from some other source, such as a query result, you'll need to decide between several options:
Use JSON_NUMERIC_CHECK when you json_encode (keep in mind that it won't only convert that column to a number; it will convert anything that looks like a number - you can see various warnings about that in the comments on this answer and on the PHP documentation)
Figure out how to make adjustments to the data source or the way you fetch the data so that the array you get will already have ints instead of strings (for example, turning off emulated prepares in PDO)
Convert the value in the array before you json_encode. There are various ways to do that, $data['eCode'] = (int) $data['eCode'];, for example.
In my opinion, option 2 would be the best way to handle it.

What kind of php array is this and how do I edit it?

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

How to access/escape PHP object member with a $ character in its name?

I'm decoding some JSON (from the Youtube data API) with json_decode and it gives me an object that looks like this when var_dump()ed:
object(stdClass)[29]
public 'type' => string 'text' (length=4)
public '$t' => string 'Miley and Mandy! KCA VIDEO WINNERS' (length=34)
How can I access the $t member?
Try
$member = '$t';
$obj->$member
You may use the second argument of json_decode
$data = json_decode($text, true);
echo $data['$t'];
$t will only interpreted as a variable reference when used outside of quotes, or within double quotes ("$t"). Strings enclosed in single quotes ('$t') are not parsed for variable references.
echo $data['$t'];
Will do exactly what you want.
You can also use: $obj->{'$t'}.
Found that information in PHP documentation about Objects.

Categories