PHP and JSON - extra comma in results - php

I'm trying to return json response in the correct format but I am getting an extra 'comma' in the returned code (comma after the last item 'Pencil'):
{
"results": [{
"ItemID": 1,
"ItemName": "Ball"
}, {
"ItemID": 2,
"ItemName": "Pen"
}, {
"ItemID": 3,
"ItemName": "Pencil"
},
}]
}
I tried different things but I can't get rid of it. Would anybody have any idea how to remove it?
The code that i have is this:
<?php
print '{"results":[';
for ($i=0; $i <$numrows; $i++) {
$stmt->fetch();
$JSONArray = array(
"ItemID" => $ItemID,
"ItemName" => $ItemName
);
print ",";
print json_encode($JSONArray);
}
print "]}"
?>

You're doing it ENTIRELY wrong. You're outputting multiple independent JSON strings, which is outright wrong. JSON is a monolithic "structure", and building it piece-wise is highly risky.
Simple: DOn't do that.
You build a standard PHP array, then do ONE SINGLE encoding when you're completely done building:
$arr = array();
for(...) {
$arr[] = ... add stuff ..
}
echo json_encode($arr);

First, fetching into bound variables is causing you an extra step, second, you don't need to construct any JSON. Just get all of your rows into the proper array structure and encode:
$result = $stmt->get_result();
while($rows['results'][] = $result->fetch_array(MYSQLI_ASSOC)){}
echo json_encode($rows);
If your system supports it, just use this instead of the while loop:
$rows['results'] = $result->fetch_all(MYSQLI_ASSOC);

Related

mysql result to multidimensional json array in different structure

I am struggling to achieve the correct json array format from the mysqli resultset. I have googled extensively and tried different things.
I am sql querying e-commerce orders and attempting to output them in JSON format to post to an application, in the JSON format specified by the application developer.
First tried this, outputs each line separately , not what I want:
while ( $row = $result->fetch_assoc()) {
$orders[]=$row;
}
echo json_encode($orders, JSON_PRETTY_PRINT);
The result was
[
{
"WebOrderNumber_C": "938276",
"itemName": "B3440S"
},
{
"WebOrderNumber_C": "938276",
"itemName": "D5035G"
},
{
"WebOrderNumber_C": "938276",
"itemName": "D6015"
}
]
Second having googled again and read other questions on here, I tried this
while ( $row = $result->fetch_assoc()) {
$orders[$row['WebOrderNumber_C']][] = $row['itemName'];
}
echo json_encode($orders, JSON_PRETTY_PRINT);
The result was
{
"938276": [
"B3440S",
"D5035G",
"D6015"
]
}
The format I am trying to achieve is this. please help
{
"WebOrderNumber_C": "938276",
"shipAddress": {
"add1": "LONDON"
},
"items": [{
"itemName": "B3440S"
},
{
"itemName": "B3440S"
},
{
"itemName": "B3440S"
}
]
}
PS I am Using PHP 5.6.30 if that is relevant.
Since the array you're adding to is nested, you need to create the parent object the first time you encounter a row with that order number. You can use an associative array for that, to make it easy to tell if the object already exists.
Then you add to the nested array, and wrap the item name in the associative array with the itemName key.
while ( $row = $result->fetch_assoc()) {
$orderno = $row['WebOrderNumber_C'];
if (!isset($orders[$orderno])) {
$orders[$orderno] = [
"WebOrderNumber_C" => $orderno,
"shipAddress" => [
"add1" => $row["add1"],
// other fields here ...
],
"items" => []
];
}
$orders[$orderno]["items"][] = ["itemName" => $row['itemName']];
}
$orders = array_values($orders); // Convert from associative array to indexed
echo json_encode($orders, JSON_PRETTY_PRINT);

PHP: Targeting specific JSON array and appending POST data correctly?

I have a JSON file that, in essence, is structured like this:
[{
"name": "James",
"reviews": [
{
"stars": 5,
"body": "great!"
},
{
"stars": 1,
"body": "bad!"
}
]
},
{
"name": "David",
"reviews": [
{
"stars": 4,
"body": "pretty good!"
},
{
"stars": 2,
"body": "just ok..."
}
]
}]
Now when positing new review data for David to a PHP script, how do I target David's specific "reviews" and append it?
I have already decoded everything correctly and have access to both the decoded file and post information. I just don't know how to target David's specific reviews in the JSON array... Thank you in advance!
UPDATE - Just to be clear, everything is decoded already, the POST data and the JSON file from the server. I just need to know how to target David's reviews specifically and append it.
UPDATE 2 - Everyone, please also understand that this is in the case that the index is not known. Doing [1] would be awesome, but when someone submits, they won't know what index it is. The loop for the rendering is being done in AngularJS btw, so can't assign anything on the PHP side for the front-end.
You will have to make use of a for-loop/foreach to iterate through the array testing where arr['name'] === 'David',
then you can access arr['reviews'].
foreach ($array as $person)
{
if ($person['name'] === 'David')
{
$person['reviews'][] = array("stars"=> 3,"body"=> "pretty cool!");
break;
}
}
Edit:
You could also make a generic function for this
function findElem(arr,field,e)
{
foreach ($arr as $elem)
{
if ($elem[field] === e)
{
return $elem;
}
}
return null;
}
to call:
$elem = findElem(myArray,'name','David');
if ($elem !== null)
$elem[] = array("stars"=> 3,"body"=> "pretty cool!");
Looks like more work, but if you are going to do it repeatedly then this helps.
PHP >= 5.5.0 needed for array_column or see below for an alternate:
$array[array_search('David', array_column($array, 'name'))]['reviews'][] = array(
'stars'=>1,'body'=>'meh'
);
Instead of array_column you can use:
array_map(function($v) { return $v['name']; }, $array);
If you want specifically david's reviews, and only david's reviews... assuming that $array holds the json_decoded array:
$david_reviews = $array[1]["reviews"];
foreach($david_reviews as $review){
//Do code to retrieve indexes of array
$stars = $review["stars"] //5
$body = $review["body"] //Great!
}
If you're looking to grab reviews for each result, then user2225171's answer is what you're looking for.
json_decode($json, true) will return you the simple array of data. Then save what you need and save back with json_encode()

How to create json with objects as element from mysql multiple rows

Hi I pretty much stuck on creating json using php and mysql. I got lots of similar question and answers here but I cannot get what I want even after spending lots of time.I need my json output from mysql rows to be like
{ "application": [ { "ver": "1.0", "name": "myapp1" }, { "ver": "1.2", "name": "myapp2"}]}
I used following code for generating json,
$result=mysql_query("SELECT * FROM btrack_transaction");
$no_of_rows = mysql_num_rows($result);
$rows = array();
//retrieve and print every record
while($r = mysql_fetch_assoc($result)){
$rows[] = array('data' => $r);
}
// now all the rows have been fetched, it can be encoded
echo json_encode($rows);
But my output looks like
[[ { "ver": "1.0", "name": "myapp1" }, { "ver": "1.2", "name": "myapp2"}]]
How can I get the json format that I want .
Thanks in advance ,
while ($r = mysql_fetch_assoc($result)) {
$rows[] = $r;
}
echo json_encode(array('application' => $rows));
You need to get rid of the extra array('data' => $r) wrapper around each element (I don't know why that doesn't show up in the output you say you get), and add the array('application' => $rows) at the end to add that element.

PHP count JSON array

I have searched SO but couldn't find an answer.My PHP script is receiving some JSON by http post that looks like this:
{
"task": [
{
"task_id": "3",
"task_due": "Oct 26 11:25",
"task_completed": "FALSE",
"task_desc": "fff",
"task_time": "20131026_112531",
"task_name": "fff"
},
{
"task_id": "2",
"task_due": "Oct 26 11:25",
"task_completed": "FALSE",
"task_desc": "rff",
"task_time": "20131026_112522",
"task_name": "xff"
},
{
"task_id": "1",
"task_due": "Oct 26 11:25",
"task_completed": "FALSE",
"task_desc": "fggg",
"task_time": "20131026_112516",
"task_name": "ff"
}
]}
As you can see, there are 3 items, but when I turn it into a PHP array object and count the items, I'm returned 1, when it should be 3, here is my PHP code:
$json_tasks = $_POST["json_array"];
$task_array = json_decode($json_tasks,true);
echo count($task_array);
And echo count prints out '1' not '3'.
Try echo count($task_array['task']);
In general, if you wonder what the structure of the value of a variable $var is, do a
<pre><?php var_export($var, true); ?></pre>
Advantage of this function over alternatives such as serialize and print_r is, that it prints PHP code (and is thus readable by anyone who understands PHP (which is likely if you program in PHP)). Disadvantage of var_export is, that it cannot handle circular structures (e.g. if $a->b == $a), but neither can JSON.
Well the 3 items are in 1 item "task" so, you have one array named task and the 3 elements are in it
try
echo count($task_array['task']);
EDIT :
please use the below code to print the array in correct pattern
echo '<pre>';
print_r($task_array['task']);
exit();
$task_array = json_decode($json_tasks);
count($task_array->task);
EX: 3
From Taiwan
try this code, here i can able to count the number of objects with specific value
here's my data.json file content
{"likes":[
{"user_id":1,"time":"12:04pm"},
{"user_id":2,"time":"02:04pm"},
{"user_id":67,"time":"11:04pm"},
{"user_id":1,"time":"12:04pm"}
]}
here's the php code
<?php
$jsonData = file_get_contents("data.json");
$data = json_decode($jsonData,true);
$total = 0;
foreach ($data["likes"] as $value) {
if($value["user_id"]==1){
$total = $total+1;
}
}
echo $total;
?>
output will be
2

Can/Should JSON format be condensed?

A sql query returns many rows of the following simple structure:
"name", id
I need to provide it in JSON format. I assume the proper format is an array of the simple structures as seen below. Although I'm not sure if there is a less verbose structure that would be preferable. for example, should I avoid the repeating name/id field names somehow to reduce size?
[
{
"name": "greg",
"id": 13
},
{
"name": "greg",
"id": 12
},
{
"name": "greg",
"id": 11
}
]
Here is the php i use to generate the json:
$rows = array();
while($r = $result->fetch_assoc())
{
$rows[] = $r;
}
echo json_encode($rows, JSON_NUMERIC_CHECK | JSON_PRETTY_PRINT);
You could serve it in the form of a 2d array, but I don't think it makes much of a difference.
Simple example to make that happen:
$rows = array();
while($r = $result->fetch_assoc())
{
$rows[$r["name"]][] = $r["id"];
}
echo json_encode($rows);
Which would give you an array grouped by names.
Also, seeing as this output is sent to the browser, it should be minified.
The user doesn't (at least, doesn't need to) see the actual JSON report, it is used by his browser as JavaScript variables.
Because of that, there's no benefit in providing a prettified version, plus, you're bloating the content length and use more bandwidth.
Bottom Line: Server JSON as compressed and minified as possible.

Categories