I want to echo everything from table that matched the criteria, currently it should be 3 rows that match, but it echoes out only 1.
public function fetchInventoryItems($user_id)
{
try
{
$stmt = $this->db->prepare("SELECT * FROM items WHERE item_owner=?
AND inventory=?");
$stmt->execute([$user_id,'1']);
if ($stmt->rowCount() > 0)
{
while($userRows = $stmt->fetch(PDO::FETCH_ASSOC))
{
$itemId = $userRows['item_id'];
$stmt = $this->db->prepare("SELECT * FROM items_db WHERE
item_id=?");
$stmt->execute([$itemId]);
while($itemRows = $stmt->fetch(PDO::FETCH_ASSOC))
{
echo '<div class="dragcontainer inventory" ><div
id="'.$itemRows['item_id'].'" class="item '.$itemRows['item_type'].'"
style="background-image:url('.$itemRows['item_icon'].')" draggable="true">
</div></div>';
}
}
}
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
first fetch should retrieve 3 rows but the while loop only cycles once.
i guess it has something to do with PDO but i dont know what exactly
In the line...
$stmt = $this->db->prepare("SELECT * FROM items_db WHERE item_id=?");
Your overwriting the use of $stmt in the outer loop. Change this and any uses of this version to something else ($stmt1 would do)...
$stmt1= $this->db->prepare("SELECT * FROM items_db WHERE item_id=?");
You could rework both these SQL queries into 1 SQL statement, which would reduce the overhead and stop this sort of issue.
Related
I'm looking for a way to SELECT from database, then check the result, and then output rows in a while loop (IF the result was above zero)
I really want to avoid using a separate count query
Right now I use this:
$sql = 'SELECT id, username, usercity, usercountry FROM siteusers WHERE userage > 50';
$STH = $conn->query($sql);
$arr = $STH->fetchAll();
if (count($arr) > 0) {
echo '<div id="users">';
foreach ($arr as $row) {
echo '<h1>'.$row['username'].</h1>';
}
echo '</div>';
}
It works. But isn't there a way I can check result/numrows and loop the rows, without using fetchAll and custom for-each loop?
Or does it not matter at all? (is for-each just as good as while loop?)
If I do it like this, the first row is not included in the while loop:
$sql = 'SELECT id, username, usercity, usercountry FROM siteusers WHERE userage > 50';
$STH = $conn->query($sql);
if ($row = $STH->fetch()) {
echo '<div id="users">';
while ($row = $STH->fetch()) {
echo '<h1>'.$row['username'].</h1>';
}
echo '</div>';
}
EDIT: I DO need to check the result, for dynamic layout purposes
You can use the PDO method rowCount to verify before your foreach if there are rows
$STH = $conn->query($sql);
if ($STH->rowCount())
{echo '<div id="users">';
foreach ($STH->fetchAll() as $row)
{
echo '<h1>'.$row['username'].'</h1>';
}
echo '</div>';
}
http://php.net/manual/en/pdostatement.rowcount.php
note that this uses up a lot of memory as all your results are loaded at once in memory with fetchAll(). if you have very large result sets, consider using a while instead of the foreach
while ($row = $STH->fetch())
{// foo with $row
}
$row is being set to the first row of your results inside of your if statement. This means that your while loop will start at the second row.
$sql = 'SELECT id, username, usercity, usercountry FROM siteusers WHERE userage > 50';
$STH = $conn->query($sql);
echo '<div id="users">';
while ($row = $STH->fetch()) {
echo '<h1>'.$row['username'].</h1>';
}
echo '</div>';
The while loop will run if there is any results to fetch, and if there aren't, then respectively it won't run.
i want to check the rows if there are any events that are binded to a host with host_id parameter, everything is well if there is not any events binded to a host, its printing out none, but if host is binded to one of the events, its not listing the events, but if i remove the codes that i pointed below with commenting problem starts here and problem ends here, it lists the events. I'm using the fetchAll function above too for another thing, there is not any such that error above there, but with the below part, it's not listing the events, how can i fix that?
Thanks
try
{
$eq = "SELECT * FROM `events` WHERE `host_id` = :id AND `confirmed` = '1' ";
$eq_check = $db->prepare($eq);
$eq_check->bindParam(':id', $id, PDO::PARAM_INT);
$eq_check->execute();
//problem starts here
$count3 = $eq_check->fetchAll();
$rowCount = count($count3);
if ($rowCount == 0)
{
echo "None";
}
//problem ends here
while($fetch = $eq_check->fetch (PDO::FETCH_ASSOC) )
{
$_loader = true;
$event_id = $fetch['event_id'];
$event_name = $fetch['event_name'];
$link = "https://www.mywebsite.com/e/$event_id";
echo "<a target=\"_blank\" href=\"$link\"><li>$event_name</li></a>";
}
}
catch(PDOException $e)
{
$log->logError($e." - ".basename(__FILE__));
}
Thank you
You can't fetch twice without executing twice as well. If you want to not just re-use your $count3 item, you can trigger closeCursor() followed by execute() again to fetch the set again.
To reuse your $count3 variable, change your while loop into: foreach($count3 as $fetch) {
The reason that it is not listing the events when you have your code is that the result set is already fetched using your fetchAll statement (The fetchAll doesn't leave anything to be fetched later with the fetch).
In this case, you might be better off running a select count(*) to get the number of rows, and then actually running your full query to loop through the results:
An example of this in PDO is here:
<?php
$sql = "SELECT COUNT(*) FROM fruit WHERE calories > 100";
if ($res = $conn->query($sql)) {
/* Check the number of rows that match the SELECT statement */
if ($res->fetchColumn() > 0) {
/* Issue the real SELECT statement and work with the results */
$sql = "SELECT name FROM fruit WHERE calories > 100";
foreach ($conn->query($sql) as $row) {
print "Name: " . $row['NAME'] . "\n";
}
}
/* No rows matched -- do something else */
else {
print "No rows matched the query.";
}
}
$res = null;
$conn = null;
?>
Note that you cannot directly use rowCount to get a count of rows selected - it is meant to show the number of rows deleted and the like instead.
My function looks like that.
private function generateTree($courseID) {
$q = "SELECT l.id, l.name AS lesson_name, c.name AS course_name FROM lessons AS l, courses AS c WHERE l.course_id=c.id AND c.id=?";
$stmt = $this->db->prepare($q);
$stmt->bind_param("i", $courseID);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows > 0) {
$stmt->bind_result($id, $lName, $cName);
echo "<li> <a href='#'>$cName</a> <ul>";
while ($stmt->fetch()) <====HERE!!!
echo "<li> <a href='?course=$courseID&lesson=$id'> $lName </a></li>";
echo "</ul> </li>";
}
}
The problem is that I'm starting to fetch data inside a while condition, but I need it before the while, too. Can I fetch data twice? Any other suggestions?
It's been four years, but in case someone stumble upon this question like I did:
while ($stmt->fetch()) {
// do your thing
}
$stmt->data_seek(0);
while ($stmt->fetch()) {
// do something other
}
You can read documentation here
You can use fetchAll() to fetch all the data and iterate over it as many times as you want.
$result = $stmt->fetchAll(); // PDO
$result = $stmt->fetch_all(); // MySQLi
foreach($result as $row) { print $row['lesson_name']; }
foreach($result as $row) { print $row['lesson_name']; }
foreach($result as $row) { print $row['lesson_name']; }
etc...
Update: I'm not entirely sure what you are doing as you seem to have several ideas mixed into your code. Perhaps you want something like this?
$q = "SELECT l.id, l.name AS lesson_name, c.name AS course_name FROM lessons AS l, courses AS c WHERE l.course_id=c.id AND c.id=?";
$stmt = $this->db->prepare($q);
$stmt->bind_param("i", $courseID);
$stmt->execute();
if ($stmt->num_rows > 0)
{
$results = $stmt->fetch_all();
foreach($results as $row)
{
print_r($row);
}
}
I think you can make your database query class in a way that it returns an array of database result. You can use data as many times you want.
You can make an array of the database-resultset like this:
while($row = mysql_fetch_assoc($result))
{
$results[] = $row;
}
I recently implemented PDO and noticed that my query results lacked the first row. That's probably because fetchColumn() retrieves the first row and moves the pointer to the second row so that the while() loop starts at row 2. Is that correct? If so, how can I avoid that and improve the following code block?
$STH = $DBH->prepare("SELECT * FROM users");
$result = $STH->execute();
if (!$result)
{
return false;
}
elseif($STH->fetchColumn()>0)//counterpart of mysql_num_rows()
{
while ($row = $STH->fetch())
{
...
}
}
}
Is that correct?
Yes. Also, fetchColumn() is not an equivalent for mysql_num_rows(). Instead, fetchColumn() retrieves the indexed column value (defaulting to index 0) of the current row and as assumed, advances the cursor.
If you need a count of the number of rows returned in your query, I suggest you first issue a SELECT COUNT(1) ... query with the same conditions, using fetchColumn() to return the count.
See example #2 on this manual page - http://www.php.net/manual/en/pdostatement.rowcount.php
For example
$stmt = $DBH->query('SELECT COUNT(1) FROM users');
// using a straight PDO::query() call as a prepared statement would be
// overkill for these queries
if ($stmt->fetchColumn() == 0) {
return false;
}
$stmt = $DBH->query('SELECT * FROM users');
while ($row = $stmt->fetch()) {
...
}
After googling around I came up with this solution:
$STH = $DBH->prepare("SELECT * FROM users");
if(!$STH)
{
$error = $DBH->errorInfo();
}
else
{
$result = $STH->execute();
if($result===false)
{
return false;
}
else
{
$rows = $STH->fetchAll(PDO::FETCH_ASSOC);
if(count($rows) > 0)
{
foreach ($rows as $row)
{
...
}
}
}
}
}
In the past I would do something like so:
$sql = 'SELECT * FROM customers WHERE customer_email="' . mysql_real_escape_string($_POST['customer_email']) . '" ';
$res = mysql_query($sql);
// if there are no hits...
if(mysql_num_rows($res) == FALSE) {
Today I am doing the same thing however with prepared statements:
$stmt = $dbh->prepare("SELECT * FROM customers where customer_email = ? LIMIT 1");
if ($stmt->execute(array($_POST['customer_email']))) {
The 2nd line of my prepared statement if($stmt... is that "if this query gets a result" or is it "if this query is executed regardless of results or not ie if it executes without error".
What I'm trying to work out is with prepared statements how do you do the equivalent of mysql_num_rows() == FALSE?
Thanks!!
You can use the rowCount() method of PDOStatement to get the number of rows returned:
$stmt = $dbh->prepare("SELECT * FROM customers where customer_email = ? LIMIT 1");
$stmt->execute(array($_POST['customer_email']));
if($stmt->rowCount() > 0) {
//fetch stuff...
}
Or, if rowCount() proves to be unreliable, you can do this:
$all = $stmt->fetchAll();
if(count($all)) {
//loop through the set...
}
PDOStatement::rowCount() returns the number of rows affected by a DELETE, INSERT, or UPDATE statement and not the number of rows returned by select query,
for select query I use :
fetchAll(PDO::FETCH_OBJ);
And
echo count($lignes);
<?php
$PARAM_hote='localhost';
$PARAM_port='3306';
$PARAM_db='test';
$PARAM_user='root';
$PARAM_pwd='';
try
{
$connexion = new PDO('mysql:host='.$PARAM_hote.';dbname='.$PARAM_db, $PARAM_user,$PARAM_pwd);
}
catch(Exception $e)
{
echo 'Erreur : '.$e->getMessage().'<br />';
echo 'N° : '.$e->getCode();
}
$requete_prepare_1=$connexion->prepare("SELECT * FROM `test_mysql`");
$requete_prepare_1->execute();
$lignes=$requete_prepare_1->fetchAll(PDO::FETCH_OBJ);
echo count($lignes);
?>