Strange JSON output from PHP json_encode() - php

I'm playing with JSON using PHP. I'm using json_encode() function to create JSON. Hovewer I've got strange JSON output:
[
{
"0": "1",
"1": "test",
"2": "test",
"ID": "1",
"title": "test",
"imageUrl": "test"
},
{
"0": "2",
"1": "welcome",
"2": "http://overkiller.pl/Smokopedia/Images/01.jpg",
"ID": "2",
"title": "welcome",
"imageUrl": "http://overkiller.pl/Smokopedia/Images/01.jpg"
}
]
Why I am getting this sort JSON how to get rid these numbers from it?
My PHP code:
<?php
header('Content-type: application/json');
$connection = mysql_connect('localhost', 'root', 'sam1');
$array = array();
if($connection)
{
mysql_select_db("Smokopedia");
$result = mysql_query("Select * from mainMenu");
if($result)
{
while ($row = mysql_fetch_array($result))
{
array_push($array, $row);
}
echo json_encode($array);
}else
{
$errorJson = array(
message => 'Result is empty or incorrect',
type => 'error'
);
echo json_encode($errorJson);
}
}
mysql_close();
?>

mysql_fetch_array includes both numeric indexed keys and column name indexed keys.
Change it to mysql_fetch_assoc and you'll get the end result you need.
Note though, that the entire mysql extension is deprecated and you should consider switching to PDO or Mysqli.

The issue is you are fetching an array, which includes both numerical indexes and string keys.
Change to mysql_fetch_assoc
while ($row = mysql_fetch_ssoc($result))
Side note: the mysql_* library is deprecated. Considered upgrading to a modern API such as MySQLi or PDO.

Related

PHP/json_encode: dealing with mixed arrays and objects with numeric properties

I recently had to tackle a bug in a legacy PHP application. This application receives a request from another application with JSON of the form:
{
"someList": [
"item A",
"item B"
],
"ratings": {
"0": 0.001234,
"1": 0.0666,
"2": 0.09876,
"3": 0.777777
}
}
When this is deserialized to a native PHP "associative array", both the list and the map (with keys 0, 1, 2, and 3) look like lists. That's fine, I can work around that. However, this application does calculations on this data and adds some more to it before serializing back to JSON in roughly the same format and sends it along to another application. Here's where the problem is. Out of the box json_encode($data) of the above results in:
{
"someList": [
"item A",
"item B"
],
"ratings": [
0.001234,
0.0666,
0.09876,
0.777777
]
}
My keys are all gone...
I see that I can use JSON_FORCE_OBJECT a la echo json_encode($data, JSON_FORCE_OBJECT) but then I get:
{
"someList": {
"0": "item A",
"1": "item B"
},
"ratings": {
"0": 0.001234,
"1": 0.0666,
"2": 0.09876,
"3": 0.777777
}
}
Now I've got keys in the first list, which I don't want. Is there a way to serialize this JSON such that someList will be a list (no keys) and ratings will be a map/object (with keys 0, 1, 2, and 3)?
When calling json_encode on an array list, with numeric coherent indexes starting with 0, PHP will treat the list as an indexed array, and not an associative array. To force php to treat it as an associative array, you can cast the array to an object before calling json_encode.
Example:
$somelist = ["item A", "item B"];
$ratings = [0.001234, 0.666, 0.09876, 0.777777];
$final = ['someList' => $somelist, 'ratings' => (object) $ratings];
echo json_encode($final);
Output:
{["item A","item B"],{"0":0.001234,"1":0.666,"2":0.09876,"3":0.777777}}
I've also struggled with returning JSON with both regular arrays and objects with numeric keys in the same response.
A solution I found is that you can build up a stdObject and defining the keys using $obj->{'0'} for example.
Here's a full example:
$decoded = json_decode('{
"someList": [
"item A",
"item B"
],
"ratings": {
"0": 0.001234,
"1": 0.0666,
"2": 0.09876,
"3": 0.777777
}
}', true);
// Do stuff with $decoded['ratings']
$ratings = new \stdClass;
foreach ($decoded['ratings'] as $key => $rating) {
$ratings->{$key} = $rating;
}
echo json_encode([
'someList' => $decoded['someList'],
'ratings' => $ratings
]);
Which then will output the following:
{
"someList": [
"item A",
"item B"
],
"ratings": {
"0": 0.001234,
"1": 0.0666,
"2": 0.09876,
"3": 0.777777
}
}
I wouldn't normally suggest "building" JSON manually, but concatenating bits of valid JSON should be fairly safe, and I think it's the only way you'll get this working.
$somelist = ["item A", "item B"];
$ratings = [0.001234, 0.666, 0.09876, 0.777777];
$json = sprintf(
'{"somelist":%s,"ratings":%s}',
json_encode($somelist),
json_encode($ratings, JSON_FORCE_OBJECT)
);
echo $json;
Or in case you have a larger object to work with, you can loop over the data to do this programmatically.
$original_json = '{"someList":["item A","item B"],"ratings""{"0":0.001234,"1":0.0666,"2":0.09876,"3":0.777777}}';
$data = json_decode($original_json);
// do whatever you need to do with the data
array_walk($data->someList, function(&$v, $k){$v .= " is changed";});
$vsprintf_args = [];
$format_str = "{";
foreach($data as $k=>$v) {
$format_str .= '%s:%s,';
$vsprintf_args[] = json_encode($k);
$vsprintf_args[] = json_encode($v, ($k === "ratings" ? JSON_FORCE_OBJECT : 0));
}
$format_str = trim($format_str, ",") . "}";
$json = vsprintf($format_str, $vsprintf_args);
echo $json;
Output:
{"somelist":["item A","item B"],"ratings":{"0":0.001234,"1":0.666,"2":0.09876,"3":0.777777}}
Was able to find a solution by using stdClass instead of an associative array when decoding the original JSON via json_decode($json, false);. Then when json_encodeing the resulting stdClass the keys will be preserved.
Here's a full example:
<?php
$json = <<<JSON
{
"someList": [
"item A",
"item B"
],
"ratings": {
"0": 0.001234,
"1": 0.0666,
"2": 0.09876,
"3": 0.777777
}
}
JSON;
// Passing false for the second param (or omitting it)
// returns a stdClass instead of associative array
$data = json_decode($json, false);
echo json_encode($data, JSON_PRETTY_PRINT);
Which outputs:
{
"someList": [
"item A",
"item B"
],
"ratings": {
"0": 0.001234,
"1": 0.0666,
"2": 0.09876,
"3": 0.777777
}
}

How can I define an array without a key within another array?

The title sounds a bit confusing, although I'm sure there's a simple solution. I'm using json_encode and am working on a web API. The web API will echo an array that is json_encoded. I want it to look like this:
{
{
"id": "test",
"reason": "test reason"
},
{
{
"id": "test2",
"reason": "test reason2"
}
}
I've tried this:
$array = array();
$array[""] = array();
$array[""]["id"] = "test";
$array[""]["reason"] = "test reason";
$array[""] = array();
$array[""]["id"] = "test";
$array[""]["reason"] = "test reason";
This still has a key though ("") which is annoying. I don't want a key. How can I fix this? Thanks! :)
I think this is more in line with your original code, you nearly had it nailed
<?php
$array = array();
// create 1st detail entry
$arrayDetail = array();
$arrayDetail["id"] = "test";
$arrayDetail["reason"] = "test reason";
$array[] = $arrayDetail; // add detail to array
// create 2nd detail entry
$arrayDetail = array();
$arrayDetail["id"] = "test";
$arrayDetail["reason"] = "test reason";
$array[] = $arrayDetail; // add detail to array
// show the output
var_dump(json_encode($array, JSON_PRETTY_PRINT));
{
{
"id": "test",
"reason": "test reason"
},
{
{
"id": "test2",
"reason": "test reason2"
}
}
This cannot be done for good reason : in javascript, the curly brackets indicate an object. Within an object, each property must have a key. The brackets on the other end indicate a numerically-indexed Array.
The Array type in php may be confusing because it's an all-in-one array, you can mix and match the keys as you see fit.
So this, instead, is valid JSON and might be what you really need (if you don't care about the keys, you'll need to loop over the values):
[
{
"id": "test",
"reason": "test reason"
},
{
{
"id": "test2",
"reason": "test reason2"
}
]
EDIT
You may create such an array in php through json_encode() like this :
$array = [["id"=> "test","reason"=> "test reason"],["id"=> "test","reason"=> "test reason"]];
echo json_encode($array);
You may get such format as below with array_push method,
$array = array();
array_push($array, array('id' => 'test', 'reason' => 'test reason' ) );
echo json_encode($array);
The resut will be a valid json format as
[{"id":"test","reason":"test reason"}]

PHP/MYSQL/JSON: Simplify JSON for API

Hi I am trying to create an API that converts a results array from a database call into json that can be easily parsed.
Using the simple command json_encode, my JSON is a complicated, verbose mess of nested objects and arrays that is proving hard to parse on the other end.
Can anyone suggest a way to pare this down to the key information that should be provided: userid, long comment (lcom) and short comment (shcom) and how to send this as an API?
Thanks in advance for any suggestions
Here is the current JSON output produced from the following query and code:
$sql = "SELECT userid,shcom,lcom FROM comments WHERE userid = 1 LIMIT 4";
$res = mysql_query($sql) or die(mysql_error());
$comments = array();
while($row = mysql_fetch_array($res)) {
$comments[] = array('row'=>$row);
}
echo json_encode(array('comments'=>$comments));
Json output:
{
"comments": [
{
"row": {
"0": "1",
"userid": "1",
"1": "hello",
"shcom": "hello",
"2": "hellothere",
"lcom”: "hellothere"
}
},
{
"row": {
"0": "1",
"userid": "1",
“1”: ”agreed”,
"shcom”: ”agreed”,
“2”: ”agreedforonce”,
"lcom”: ”agreedforonce”
}
},
{
"row": {
"0": "1",
"userid": "1",
"1": "gohome",
"shcom”: ”gohome“,
“2”: ”gohomenow”,
"lcom: ”gohomenow”
}
},
{
"row": {
"0": "1",
"userid": "1",
"1": "getout”,
"shcom”: ”getout”,
“2”: ”getoutofhere”,
"lcom: ”getoutofhere”
}
}
]
}
You should be using mysqli rather than mysql since mysql is deprecated. Regardless, the problems in your code are happening because of two reasons. One, mysql_fetch_array does not produce the results you are expecting. Two, in your iteration you are not extracting the answers the right way. To resolve, use mysq_fetch_assoc and push only each $row to your final array.
Replace this:
while($row = mysql_fetch_array($res)) {
$comments[] = array('row'=>$row);
}
to this:
while($row = mysql_fetch_assoc($res)) {
$comments[] = $row;
}

Json_Encode php last comma

For a school project I have to display database data as a valid json file.
$result = mysqli_query($mysqli, "SELECT * FROM `csvdata`");
echo "{ \"films\" : [";
while ($row = mysqli_fetch_array($result)) {
$jsonResult = json_encode($row);
echo $jsonResult;
echo ",";
}
echo "]}";
The output i get is:
{
"films": [
{
"0": "Man on fire",
"titel": "Man on fire",
"1": "Actie",
"genre": "Actie"
},
{
"0": "Dumb and Dumberer",
"titel": "Dumb and Dumberer",
"1": "Comedy",
"genre": "Comedy"
},
{
"0": "DefQon 2014",
"titel": "DefQon 2014",
"1": "Muziek",
"genre": "Muziek"
},
]
}
Now my question is, how do I remove the last comma, I cannot find that. And all data tells the data 2 times, I also don't know how to avoid this.
Let json_encode handle the entire thing - build one array of data, and use json_encode on that.
$result = mysqli_query($mysqli, "SELECT * FROM `csvdata`");
$response = array();
$response['films'] = array();
while ($row = mysqli_fetch_array($result)) {
$response['films'][] = $row;
}
echo json_encode($response);
A good way to do this, is to not place a comma after writing every record, but instead before every record.
Then all you have to do, is add an if statement that doesn't output the comma for the very first row.

How to retrive the following json data in php

i've the following json data with the following structure
{
"page": 0,
"items": 43,
"total": 43,
"incentiveItems": {
"incentiveItem": [
{
"#id": "1111",
"name": "...",
"program": {
"#id": "6765",
"$": "NAME"
},
"admedia": {
"admediumItem": {
...
and more, to parse the data in php i do a simple foreach...
$obj = json_decode($jsonData);
echo $obj->items;
echo '<table><tr><td>Nome</td><td>Descrizione</td><td>Codice</td></tr>';
foreach($obj->incentiveItems->incentiveItem as $programma ) {
so, the problem is that i can't call the "$" :" NAME" value, coz if i use (for ex)
$programma->program->$
$programma->program['$']
$obj->incentiveItems->incentiveItem->program->$ or ['$']
it crash
and the same is for the #id field.
can someone help me? Thanks
Tyr decoding json as associative array:
$obj = json_decode($jsonData, true);
echo $obj['items'];
echo '<table><tr><td>Nome</td><td>Descrizione</td><td>Codice</td></tr>';
foreach($obj['incentiveItems']['incentiveItem'] as $programma ) {
echo $programma['#id'];
I believe you can use single quotes and curly brackets to access it
$obj->incentiveItems->incentiveItem->program->{'$'}
$obj->incentiveItems->incentiveItem->program->{'#id'}

Categories