PHP not looping as I would like - php

From the code below, this what I'm trying to achieve: If citizenID found by the $get_friends query are 1 and 2. I would like the while loop to first get all the rows for 1 and then do the same for 2. The code I currently have below its only retrieving the last row for 1 and 2. Please help.
<?php
include ('session_start.php');
include_once('db_connect_universal.php');
$user_id = $_SESSION['sess_id'];
//GET USER FRIENDS AND DETAILS
$get_friends = "SELECT * FROM citizens
INNER JOIN user_details
ON citizens.citizenID=user_details.UserID
WHERE citizens.userID = '".$user_id."'";
$results_get_friends = $conn->query($get_friends);
$num_rows_friends = mysqli_num_rows ($results_get_friends);
while ($row_friends = $results_get_friends->fetch_assoc()) {
$citizenID = $row_friends['citizenID'];
//GET RATINGS AND COMMENTS
$sql = "SELECT * FROM comments
INNER JOIN organiser ON comments.movieID=organiser.movieID
WHERE comments.userID= '".$citizenID."'
AND ratings_n_comments.Time BETWEEN DATE_SUB(CURDATE(), INTERVAL 28 DAY)
AND DATE_ADD(CURDATE(), INTERVAL 10 DAY)
ORDER BY comments.Time DESC";
$result = $conn->query($sql);
$num_rows = mysqli_num_rows ($result);
$row = $result->fetch_assoc();
$n_Rating[]= array(
'dp' => $row_friends['display_pics'],
'uname' => $row_friends['Uname'],
'poster'=> $row['mooster'],
'title'=> $row['moitle'],
'genre'=> $row['moenre'],
'comment'=> $row['Comment'],
'mid'=> $row['mID'],
'check' => 'data'
);
}
header('Content-Type: application/json');
echo json_encode ($n_Rating);
}
//detailed error reporting
if (!$sql) {
echo 'MySQL Error: ' . mysqli_error($conn);
exit;
}
?>

You are only fetching one row with $row = $result->fetch_assoc();.
Are you trying to fetch all the comments for the users?
Because then you'll need to loop trough everything $result has just like you are doing with while ($row_friends = $results_get_friends->fetch_assoc())
Also instead of concatenating your SQL query, try using prepare and bind_param to avoid possible SQL injection

Related

How can I create an array from the results of 2 queries?

I'm trying to create an array from the results of 2 queries, and send it all together to front-end, but I'm stuck to the point where I need to push the results of the second query to the array, I tried to do it using array_push but doesn't work.
Let's say we have this example, and I need to include the results of $query2 to $return_arr
Any ideas?
<?php
header('Access-Control-Allow-Origin: *');
include "config.php";
$return_arr = array();
$query1 = "SELECT * FROM balance WHERE class='income' ORDER BY id DESC";
$query2 = "SELECT * FROM balance WHERE class='expense' ORDER BY id DESC";
$result1 = mysqli_query($conn,$query1);
while($row = mysqli_fetch_array($result1)){
$id = $row['id'];
$description = $row['description'];
$date = $row['date'];
$euro = $row['euro'];
$who = $row['who'];
$class = $row['class'];
$return_arr[] = array("id_income" => $id,
"description_income" => $description,
"date_income" => $date,
"euro_income" => $euro,
"who_income" => $who,
"class_income" => $class
);
}
// Encoding array in JSON format
echo json_encode($return_arr);
Here's a different query:
SELECT *
FROM balance
WHERE class IN('income','expense')
ORDER
BY class
, id DESC
Like JS Bach answer. But maybe you could speed up performance by mention the column's name.
SELECT column1, column2, column3 FROM balance WHERE class IN ('income','expense') ORDER BY class, id DESC;
You can also make use of OR operator
$query = SELECT * FROM balance WHERE class = "income" OR class = "expense" ORDER BY class, id DESC;
$result = mysqli_query($conn,$query);
$array = mysqli_fetch_array($result,MYSQLI_ASSOC);
Your fetched records will already be in an array format in $array
This can be more effective when dealing with tables having records in 1000s of rows

How to combine multiple query's into one?

I am running a line graph on RGraph framework, and I am using a SELECT COUNT statement for rejected, accepted, approved etc.....counting how many items was rejected or accepted etc and then dumping the query data into an array, However I am looking for an easier way to implement this query, instead of running a query on each unique row value, also thinking in the way if I have to encounter other column data besides rejected, accepted or etc....I wouldnt, my code doesnt seem very scalable then. Please help
So far, I am running a query for each keyword, hope my code explains this.
The final variable is what i am feeding to RGRAPH, This works fine as it is, however it isn't the right way, and not very scalable, should my row data change.
<?php
$cxn = mysqli_connect("localhost","root","", "csvimport");
$query = "SELECT COUNT(*) FROM table_1 WHERE conclusion = 'rejected'";
$result = mysqli_query($cxn, $query) or die(mysqli_error($cxn));
$display = mysqli_fetch_array($result);
$rejected = $display[0];
//echo $rejected;
$query = "SELECT COUNT(*) FROM table_1 WHERE conclusion =
'accepted'";
$result = mysqli_query($cxn, $query) or die(mysqli_error($cxn));
$display = mysqli_fetch_array($result);
$accepted = $display[0];
//echo $accepted;
$query = "SELECT COUNT(*) FROM table_1 WHERE conclusion = '-'";
$result = mysqli_query($cxn, $query) or die(mysqli_error($cxn));
$display = mysqli_fetch_array($result);
$dash = $display[0];
//echo $dash;
$query = "SELECT COUNT(*) FROM table_1 WHERE conclusion =
'approved'";
$result = mysqli_query($cxn, $query) or die(mysqli_error($cxn));
$display = mysqli_fetch_array($result);
$approved = $display[0];
//echo $approved;
$datarray = [$rejected, $accepted, $dash, $approved];
print_r($datarray);
$data_string = "[" . join(", ", $datarray) . "]";
echo "<br>";
print_r($data_string);
?>
You can just use GROUP BY and add the conclusion column to the result set, so
SELECT conclusion, COUNT(*) as total
FROM table_1
WHERE conclusion in ('rejected', 'accepted', '-', 'approved')
GROUP BY conclusion
Then retrieve each row of the result set
$totals = [];
while($row = mysqli_fetch_array($result)) {
$totals [$row[0]] = [$row[1]];
}
and $totals will be an array something like
array( 'accepted' => 12,
'approved' => 20...)
If you want all of the conclusions, then just remove the WHERE conclusion in line and it will return all of the possibilities along with the count.

creating outer array php

UPDATE: a solution has been found stated below: however new issue poses i didnt want to keep creating question so updated this one when i use ajax to pass through to html i get the following error response.forEach is not a function
where the code is as below is this because there are now 2 arrays?
$.get('php/test.php', function(response) {
console.log(response);
var row;
response.forEach(function(item, index) {
console.log(item);
$(`td.${item.beacon}`).css('background-color', item.location).toggleClass('coloured');
});
});
Im Pretty naff when it comes to this type of thing but i need to try get these 2 queries added to 1 ajax I have been told i should add both queries to an outer array but im not sure how to do this and the example i got was $array = $other_array
but im not sure how to write it any help would be greatly appreaciated
$sql = "SELECT beacon,TIME_FORMAT(TIMEDIFF(max(`time`),min(`time`)), '%i.%s')
AS `delivery_avg`
FROM `test`.`test`
where date = CURDATE()
and time > now() - INTERVAL 30 MINUTE
group by beacon ";
$result = $conn->query($sql);
$sql2 = 'SELECT
*
FROM
(SELECT
beacon,location,date,
COUNT(location) AS counter
FROM `test`.`test`
WHERE `date` = CURDATE() and `time` > NOW() - interval 40 second
GROUP BY beacon) AS SubQueryTable
ORDER BY SubQueryTable.counter DESC;';
$result = $conn->query($sql2);
$result = mysqli_query($conn , $sql);
$rows = array();
while($r = mysqli_fetch_assoc($result)) {
$rows[] = $r;
}
echo json_encode($rows);
$result2 = mysqli_query($conn , $sql2);
$rows2 = array();
while($r = mysqli_fetch_assoc($result2)) {
$rows2[] = $r;
}
echo json_encode($rows2);
You already got most of it right. To get the data in one go, you can combine the arrays (see the line staring with $result) and then send it JSON formatted.
$sql1 = "SELECT ...";
// Query the database
$result1 = $conn->query($sql);
// Fetch the result
$rows1 = $result1->fetch_all(MYSQLI_ASSOC);
// Same for second query
$sql2 = 'SELECT ...';
$result2 = $conn->query($sql2);
$rows2 = $result2->fetch_all(MYSQLI_ASSOC);
$result = array(
'query1' => $rows1,
'query2' => $rows2
);
header("Content-Type: application/json");
echo json_encode($result);
Some more hints:
You only need to run the query once (you have ->query() and mysqli_query() in your code).
You don't need the loop to get all result rows. The function mysqli_fetch_all() does that for you.
When you have your 2 arrays with db results, you can do something like this :
$return = array (
$result,
$result2
);
echo json_encode($return);
$sendResponse = array (
'sql1' => $sqlResult1,
'sql2' => $sqlResult2
);
echo json_encode($sendResponse);
This would be a more suitable and convenient (from JavaScript size) way
$response = [];
$response['result_first_query'] = $rows;
$response['result_second_query'] = $rows2;
echo json_encode($response);

MYSQLI_QUERY not returning values

I am trying to figure out why my query is not working. I am trying to add all the amounts together for each month where status = 'S'. However, I get the following error. Any ideas?
[05-Jul-2013 11:21:30 America/New_York] PHP Fatal error: Cannot use object of type mysqli_result as array
My Code:
$closedsales = mysqli_query($mysqli, "SELECT MONTH(date) as month, sum(amount) as total FROM sales WHERE user_id = '".$userid."' AND status = 'S' GROUP BY MONTH(date)");
while ( $row = mysqli_fetch_row($closedsales) ) {
$closedsales[$row['month']] = $row['total'];
}
UPDATE:
$closedsales = mysqli_query($mysqli, "SELECT MONTH(date) as month, sum(amount) as total FROM sales WHERE user_id = '".$userid."' AND status = 'S' GROUP BY MONTH(date)");
while ( $row = mysqli_fetch_row($closedsales) ) {
$monthlysales[$row['month']] = $row['total'];
}
foreach($monthlysales as $monthlysale) {
echo $monthlysale;
echo "This worked...";
}
Thanks! I got rid of that error. However, for some reason my array does not contain anything. It only prints out This worked...
Is it possible this is because I don't have each month in the DB?
The problem is the assignment:
$closedsales[$row['month']] = $row['total'];
$closedsales is the result returned by mysqli_query, it's not an array you can assign to. Use a different variable for this.

How can I optimise this mysql/php query?

My page displays an image, and I want to display the previous and next image that is relevant to the current one. At the moment I run the same query 3x and modify the "where" statement with =, >, <.
It works but I feel there must be a better way to do this.
The image id's are not 1,2,3,4,5. and could be 1,2,10,20,21 etc. But if it is much more efficient I am willing to change this.
mysql_select_db("database", $conPro);
$currentid = mysql_real_escape_string($_GET['currentid']);
$query ="SELECT * FROM database WHERE id ='".$currentid."' LIMIT 1 ";
$result = mysql_query($query,$conPro) or die(mysql_error());
$affected_rows = mysql_num_rows($result);
if ($affected_rows==1)
{
$row = mysql_fetch_array($result)or die ('error:' . mysql_error());
$current_id = $row['id'];
$current_header = $row['title'];
$current_description =$row['desc'];
$current_image = "http://".$row['img'];
$current_url = "http://".$row['id']."/".$db_title."/";
$current_thumb = "http://".$row['cloud'];
}
mysql_select_db("database", $conPro);
$query ="SELECT * FROM database WHERE id <'".$currentid."' ORDER BY id DESC LIMIT 1 ";
$result = mysql_query($query,$conPro) or die(mysql_error());
$affected_rows = mysql_num_rows($result);
if ($affected_rows==1)
{
$row = mysql_fetch_array($result)or die ('error:' . mysql_error());
$previous_id = $row['id'];
$previous_header = $row['title'];
$previous_description =$row['desc'];
$previous_image = "http://".$row['img'];
$previous_url = "http://".$row['id']."/".$db_title."/";
$previous_thumb = "http://".$row['cloud'];
}else{
$previous_none = "true"; //no rows found
}
mysql_select_db("database", $conPro);
$query ="SELECT * FROM database WHERE id >'".$currentid."' ORDER BY id ASC LIMIT 1 ";
$result = mysql_query($query,$conPro) or die(mysql_error());
$affected_rows = mysql_num_rows($result);
if ($affected_rows==1)
{
$row = mysql_fetch_array($result)or die ('error:' . mysql_error());
$next_id = $row['id'];
$next_header = $row['title'];
$next_description =$row['desc'];
$next_image = "http://".$row['img'];
$next_url = "http://".$row['id']."/".$db_title."/";
$next_thumb = "http://".$row['cloud'];
}else{
$next_none = "true"; //no rows found
}
mysql_close($conPro);
Thank you for your time
You don't have to do select_db each time. Once you 'select' a db, it stays selected until you select something else.
You can't really get away from doing two separate queries to get the next/previous images, but you can fake it by using a union query:
(SELECT 'next' AS position, ...
FROM yourtable
WHERE (id > $currentid)
ORDER BY id ASC
LIMIT 1)
UNION
(SELECT 'prev' AS position, ...
FROM yourtable
WHERE (id < $currentid)
ORDER BY id DESC
LIMIT 1)
This would return two rows, containing a pseudofield named 'position' which will allow you to easily identify which row is the 'next' record, and which is the 'previous' one. Note that the brackets are required so that the 'order by' clauses apply to the individual queries. Without, mysql will take the order by clause from the last query in the union sequence and apply it to the full union results.
You can get the "previous" one first WHERE id <'".$currentid."' ORDER BY id DESC, and then query for two "above" it: SELECT * FROM database WHERE id >= '".$currentid."' ORDER BY id ASC then it takes only two queries instead of three.

Categories