Datasource not available within second while loop - php

I have the following php code:
$user_id = $user["id_user_key"];
$stmt = $db->prepare("CALL spGetUserProducts(?)");
$stmt->bind_param('i', $user_id);
$stmt->execute();
$result = $stmt->get_result();
$data = array();
while($row = $result->fetch_assoc()) {
$row_array = array();
$row_array["id"] = $row["id"];
$row_array["pname"] = $row["pname"];
$row_array["picon"] = $row["picon"];
$row_array["menuItems"] = array();
$product = $row["id"];
//loop
$result_opt = $db->query("CALL spGetUserProductViews($user_id, $product)");
while ($opt_fet = $result_opt->fetch_assoc()) {
$row_array["menuItems"][] = array(
"id" => $opt_fet["id"],
"vname" => $opt_fet["vname"],
"isheader" => $opt_fet["isheader"]
);
}
array_push($data, $row_array);
}
$stmt->close();
echo json_encode($data);
The first loop can get a hold of $db, in other words: the first prepared statement is being excecuted and gives me results. The second one:
$result_opt = $db->query("CALL spGetUserProductViews($user_id, $product)");
gives me false. When I try this statement outside the loop, it does work.
Any thoughts ont his?

I found out that mysqli can't handle two simultaneous queries because mysqli uses unbuffered queries by default. Now, I could have dived into this (for example make use of $stmt->store-result()), but I also realized that I would like to keep the load on my database to a minimum.
My solution:
$data = array();
$user_id = $user["id_user_key"];
//menus -> products
$stmt = $db->prepare("CALL spGetUserProducts(?)");
$stmt->bind_param("i", $user_id);
$stmt->execute();
$result = $stmt->get_result();
$menus = array();
while($row = $result->fetch_assoc()) {
$menus[] = $row;
}
$stmt->close();
//items -> views
$stmt = $db->prepare("CALL spGetUserProductViews(?)");
$stmt->bind_param("i", $user_id);
$stmt->execute();
$result = $stmt->get_result();
$items = array();
while($row = $result->fetch_assoc()) {
$items[] = $row;
}
$stmt->close();
//generate object
//loop menus
foreach($menus as $m){
$row_array = array();
$row_array["id"] = $m["id"];
$row_array["pname"] = $m["pname"];
$row_array["picon"] = $m["picon"];
$row_array["menuItems"] = array();
//loop items
foreach($items as $i) {
if($m["id"] == $i["id_product"]) {
$row_array["menuItems"][] = array(
"id" => $i["id"],
"vname" => $i["vname"],
"isheader" => $i["isheader"]
);
}
}
array_push($data, $row_array);
}
echo json_encode($data);
So now I first generate arrays out of the two objects. then I do a foreach over the menus and then over the items. When the $menu["id"] equals $items["id_product"] then the array with items for that specific menu is being generated.
EDIT
After the data has been pulled from the database I first have to do a check wether or not the array contains data:
if(!empty($menus) && !empty($items)) {
foreach ($menus as $m) {
$row_array = array();
$row_array["id"] = $m["id"];
$row_array["pname"] = $m["pname"];
$row_array["picon"] = $m["picon"];
$row_array["menuItems"] = array();
//loop items
foreach ($items as $i) {
if ($m["id"] == $i["id_product"]) {
$row_array["menuItems"][] = array(
"id" => $i["id"],
"vname" => $i["vname"],
"isheader" => $i["isheader"]
);
}
}
array_push($data, $row_array);
}
}

Related

PDO While loop only gets the last data

I am trying to display a nested json as seen in this picture
JSON Ouput
However it only gets the last data. I am sure that the 1st id has a data. Please see the code below
<?php
include 'conn2.php';
$pdo = new PDO($dsn, $user, $passwd);
$stmt = $pdo->prepare("CALL sp_foods_display();");
$stmt->execute();
$stmt->bindColumn('bar_name',$bar_name);
$stmt->bindColumn('address',$address);
$stmt->bindColumn('id',$post_id);
$response = array();
$result = array();
while ($row = $stmt->fetch(PDO::FETCH_BOUND)) {
$temp["bar_name"] = $bar_name;
$temp["address"] = $address;
$temp["item_details"] = getItem($post_id);
array_push($result, $temp);
}
$response["result"] = $result;
echo "<pre>" . json_encode($response,JSON_PRETTY_PRINT) . "</pre>";
function getItem($id) {
global $pdo;
$stmt = $pdo->prepare("SELECT * FROM fct_menu_foods WHERE post_id = :cur_post_id ORDER BY id ASC");
$stmt->bindParam(":cur_post_id",$id,PDO::PARAM_INT);
$stmt->execute();
$food_details = array();
$stmt->bindColumn('food_name',$food_name);
$stmt->bindColumn('price',$price);
$stmt->bindColumn('img_name',$img_name);
while ($row = $stmt->fetch(PDO::FETCH_BOUND)) {
$temp = array();
$temp["food_name"] = $food_name;
$temp["price"] = $price;
$temp["img_name"] = $img_name;
array_push($food_details, $temp);
}
return $food_details;
}
?>
my target output is to display all data in nested.
I found a solution. My bad. You have to closeCursor(); for every query and use fetchAll for getting the data.

PHP trying to simply a repetitive script involving rowsets

I'm trying to simplify a repetitive script that I'm doing in PHP. I've looked at a few loop options but since it involves rowsets being returned from a MySQL stored procedure it's not acting properly. I'm doing this same script about 15 times to return all the data. Ultimately I'm looking to pass back a json_encode array to the ajax calling it. The results I keep getting when trying to put it in a loop is a 500 error or a poorly constructed array.
$stmt->execute();
$values = array();
$stmt->execute();
$values = array();
$rowCount = $stmt->rowCount();
if ($rowCount > 0) {
$row = $stmt->fetchAll(PDO::FETCH_NUM);
$values = array();
foreach ($row as $rowvalue) {
$values[] = array($rowvalue[0], $rowvalue[1], $rowvalue[2], $rowvalue[3], $rowvalue[4], $rowvalue[5]);
}
$stmt -> nextRowset();
$row = $stmt->fetchAll();
foreach ($row as $rowvalue) {
$values[] = array($rowvalue[0], $rowvalue[1], $rowvalue[2], $rowvalue[3], $rowvalue[4], $rowvalue[5]);
}
$stmt -> nextRowset();
$row = $stmt->fetchAll();
foreach ($row as $rowvalue) {
$values[] = array($rowvalue[0], $rowvalue[1], $rowvalue[2], $rowvalue[3], $rowvalue[4], $rowvalue[5]);
}
...
echo json_encode($values);
}
Updated to use the code example below:
$sql = 'CALL fo_SELECT_Operations_Detail(?,?,?)';
$facility = $_POST['facility'];
$startweek = $_POST['startweek'];
$endweek = $_POST['endweek'];
$sql->bindParam(1, $facility, PDO::PARAM_STR);
$sql->bindParam(2, $startweek, PDO::PARAM_STR);
$sql->bindParam(3, $endweek, PDO::PARAM_STR);
$stmt = $conn->query($sql);
$values = array();
do {
$rows = $stmt->fetchAll(PDO::FETCH_NUM);
foreach ($rows as $r) {
$values[] = array($r[0], $r[1], $r[2], $r[3], $r[4], $r[5]);
}
} while ($stmt->nextRowset());
// all processed so now send JSON
echo json_encode($values);
We all forget that SP's which create rowsets also create an annoying empty one as well that has to be Next'd over, but not actually unloaded. The && $stmt->columnCount() looks after getting nextRowset() called but not actually attempting to process it in any way.
$sql = 'CALL fo_SELECT_Operations_Detail(?,?,?)';
$stmt->prepare($sql);
$stmt->bindParam(1, $_POST['facility'], PDO::PARAM_STR);
$stmt->bindParam(2, $_POST['startweek'], PDO::PARAM_STR);
$stmt->bindParam(3, $_POST['endweek'], PDO::PARAM_STR);
$stmt = $conn->execute();
$values = array();
do {
$rows = $stmt->fetchAll(PDO::FETCH_NUM);
foreach ($rows as $r) {
$values[] = [$r[0], $r[1], $r[2], $r[3], $r[4], $r[5]];
}
} while ($stmt->nextRowset() && $stmt->columnCount());
// all processed so now send JSON
echo json_encode($values);

Categories Multi Level display using php and mysql in json format

I need to display categories and its sub categories in json format, here problem is each category has unlimited levels, some categories has 4 levels and some 2 and some 3 levels. I have tried one solution it is showing only one under level, but I need to show all levels.
Table schema:
Code Example:
function categories() {
header('Content-Type: application/json');
$sql = "select id,name,parent_id from categories where parent_id = 0";
$q = $this->db->conn_id->prepare($sql);
$q->execute();
$main_cat = array();
while ($row = $q->fetch(PDO::FETCH_ASSOC)) {
$sql2 = "select id,name,parent_id from categories where parent_id = ?";
$sub_cat = array();
$r = $this->db->conn_id->prepare($sql2);
$r->bindParam(1, $row['id']);
$r->execute();
while ($row1 = $r->fetch(PDO::FETCH_ASSOC)) {
array_push($sub_cat, array_filter($row1));
}
$row['subcategories'] = $sub_cat;
array_push($main_cat, array_filter($row));
}
echo json_encode(array("categories" => $main_cat));
}
Above Code Json Response Example:
{"categories":[{"id":"1","name":"Development","subcategories":[{"id":"2","name":"All Development","parent_id":"1"},{"id":"3","name":"Web Development","parent_id":"1"},{"id":"12","name":"Mobile Apps","parent_id":"1"}]},{"id":"4","name":"Design","subcategories":[{"id":"5","name":"All Design","parent_id":"4"}]},{"id":"11","name":"IT & Software"}]}
Any one can help me how to solve this issue.
I have tried this solution works for me.
function categories() {
$sql = "SELECT * FROM categories where parent_id = 0";
$results = $this->db->conn_id->prepare($sql);
$results->execute();
while ($result = $results->fetch(PDO::FETCH_ASSOC)) {
$subcat = array();
$id = $result['id'];
$childs = $this->hasChilds($id);
$categories[] = array("id" => $result['id'], "name" => $result['name'], "parent_id" => $result['parent_id'], "subcats" => array_filter($childs));
}
echo json_encode($categories);
}
function hasChilds($id) {
$sql = "SELECT * FROM categories where parent_id = ? ";
$results = $this->db->conn_id->prepare($sql);
$results->bindParam(1, $id);
$results->execute();
$count = $results->rowCount();
$array = array();
if ($count > 0) {
while ($result = $results->fetch(PDO::FETCH_ASSOC)) {
$array[] = array("id" => $result['id'], "name" => $result['name'], "parent_id" => $result['parent_id'], "subcats" => array_filter($this->hasChilds($result['id'])));
}
} else {
$array[] = null;
}
return $array;
}

Convert/query array into JSON with PHP

I have a SELECT query that results in something like this:
USER_ID: 000030 USERNAME: Oprah RATING: 5
USER_ID: 000033 USERNAME: Pitbull RATING: 8
What I need is to display it in this form:
[[{"USER_ID":"000030","USERNAME":"Oprah","RATING":"5"},{"USER_ID":"000033","USERNAME":"Pitbull","RATING":"8"}]]
Generally I get this desired result with this SELECT:
try {
$stmt = $conn->prepare("SELECT USER_ID, USERNAME, RATING FROM table");
$stmt -> execute(array($userid));
while($row = $stmt->fetchAll(PDO::FETCH_ASSOC)) {
$output[] = $row;
}
}
print(json_encode($output));
But this time I had to get the result in this form:
try {
$stmt = $conn->prepare("SELECT USER_ID, USERNAME, RATING FROM table");
$stmt -> execute(array($userid));
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
//$output[] = $row;
$row2[$i][$j] = $row['USER_ID'];
$j++;
$row2[$i][$j] = $row['USERNAME'];
$j++;
$row2[$i][$j] = $row['RATING'];
$i++;
$j=0;
}
}
How can I convert it into the desired form or form the query to produce it?
I tried these:
print(json_encode($row2));
[["000030","Oprah","5"],["000033","Pitbull","8"]]
$output[] = $row2;
print(json_encode($output));
[[["000030","Oprah","5"],["000033","Pitbull","8"]]]
For json_encode() to produce a json string that includes the associative indices, they need to be in the array you are encoding. If the indices are 0, 1, 2, etc., the indices will not show up in the json string.
Try this:
$i=0;
while(...) {
$row2[$i]['USER_ID'] = $row['USER_ID'];
$row2[$i]['USERNAME'] = $row['USERNAME'];
$row2[$i]['RATING'] = $row['RATING'];
$i++;
}
...
print_r(json_encode($row2));
Consider this PHP snippet for clarification.
Alternative methods of building array:
while(...) {
$row2[] = array(
'USER_ID' = $row['USER_ID'],
'USERNAME' = $row['USERNAME'],
'RATING' = $row['RATING']
);
}
// OR
$i=0;
while(...) {
foreach ($row as $key => $val) {
$row2[$i][$key] = $val;
}
$i++;
}
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$output[] = array("USER_ID" => $row["USER_ID"],
"USERNAME" => $row["USERNAME"],
"RATING" => $row["RATING"],
);
}
print(json_encode($output));

PHP MySQLi select from database and push to json

$q = $db->query("SELECT * FROM user");
while($row = mysqli_fetch_array($q)) {
$product = array();
$product['id'] = $row['id'];
$product['user'] = $row['user'];
$product['data'] = $row['data'];
}
$response["product"] = array();
array_push($response["product"], $product);
I have been trying to select from a database the entire table and then loop through each result and push it to an array. The above code only seems to put to the array the last item in the table.
You're probably better off doing something like this:
$q = $db->query("SELECT * FROM user");
$response = array();
$response["product"] = array();
while($row = mysqli_fetch_array($q)) {
$product = array(
'id' => $row['id'],
'user' => $row['user'],
'data' => $row['data'],
);
array_push($response["product"], $product);
}
You were only getting the last item because you kept resetting your $response['product'] & $product array.
You need to push into the array for each item. At the moment you overwrite $product each time though the loop. Try this:
$q = $db->query("SELECT * FROM user");
$response["product"] = array();
while($row = mysqli_fetch_array($q)) {
$product = array();
$product['id'] = $row['id'];
$product['user'] = $row['user'];
$product['data'] = $row['data'];
array_push($response["product"], $product);
}

Categories