where to put while loop with mysqli fetch? - php

I am using mysqli and php to be able to select a column from the database and to also be able to insert data into the database. Now while researching mysqli, I have found out that before checking to see if the number of rows equals to 0, I need to include a while($stmt->fetch()) {
Now because I have to blocks of code, one for SELECT and other INSERT, I want to know that does the while fetch loop suppose to wrap round the whole code or does it suppose to wrap round the SELECT block of code and INSERT block of code separately?
UPDATE:
$query = "SELECT TeacherAlias FROM Teacher WHERE TeacherAlias = ?";
// prepare query
$stmt=$mysqli->prepare($query);
// You only need to call bind_param once
$stmt->bind_param("s",$getid);
// execute query
$stmt->execute();
// get result and assign variables (prefix with db)
$stmt->bind_result($dbTeacherAlias);
//get number of rows
$stmt->store_result();
$numrows = $stmt->num_rows();
$results = $stmt->fetch_all();
foreach ($results as $row) {
if ($numrows == 0){
// don't use $mysqli->prepare here
$query = "SELECT TeacherUsername FROM Teacher WHERE TeacherUsername = ?";
// prepare query
$stmt=$mysqli->prepare($query);
// You only need to call bind_param once
$stmt->bind_param("s",$getuser);
// execute query
$stmt->execute();
// get result and assign variables (prefix with db)
$stmt->bind_result($dbTeacherUsername);
//get number of rows
$stmt->store_result();
$numrows = $stmt->num_rows();
$results = $stmt->fetch_all();
}
foreach ($results as $row) {
if ($numrows == 0){
// don't use $mysqli->prepare here
$query = "SELECT TeacherEmail FROM Teacher WHERE TeacherEmail = ?";
// prepare query
$stmt=$mysqli->prepare($query);
// You only need to call bind_param once
$stmt->bind_param("s",$getemail);
// execute query
$stmt->execute();
// get result and assign variables (prefix with db)
$stmt->bind_result($dbTeacherEmail);
//get number of rows
$stmt->store_result();
$numrows = $stmt->num_rows();
$results = $stmt->fetch_all();
}
}
}
}

Try mysqli::fetch_all(), which returns an associative array:
$results = $stmt->fetch_all();
foreach ($results as $row) {
// do something...
}

// if no results found it will return either empty array or null (not sure, check it)
$results = $stmt->fetch_all();
// if $results is an empty array it will not enter the loop
foreach($results as $row) {
if ($numrows == 0){ // this is never reached if results no results were found

Related

Foreach implemented on finding array data finds only one data

Ive used two queried in a function. FIrst query to find an array of data. And second query is to select rows as per checking the array data from the first query. But the overall function return only one row data.
function getCartItems($conn)
{
$cust_id=$_SESSION['cust_id'];
$stmtSelect1 = $conn->prepare("SELECT product_id FROM tbl_cart WHERE cust_id=cust_id");
$stmtSelect1->bindParam('cust_id',$cust_id);
$stmtSelect1->execute();
$product_id= $stmtSelect1->fetchAll();
foreach($product_id as $productid) {
$stmtfetch = $conn->prepare("SELECT * FROM tbl_item WHERE product_id=:products_id");
$stmtfetch->bindParam(':products_id',$productid['product_id']);
$stmtfetch->execute();
$datas = $stmtfetch->fetchAll();
print_r($datas);
exit();
}
}
First of all, your code has typos (Missing ":" before parameter, product_id/products_id).
This should work:
$cust_id=$_SESSION['cust_id'];
$stmt = $conn->prepare("SELECT tbl_item.* FROM tbl_cart, tbl_item WHERE tbl_cart.cust_id = :cust_id AND tbl_item.product_id = tbl_cart.product_id);
$stmt->bindParam('cust_id',$cust_id);
$stmt->execute();
$rows = $stmt->fetchAll();
foreach($rows as $row)
{
print_r($row);
}

why {if row exist then fetch them} does not work?

I want to check {if row exist} first and then fetch the results. here is my code:
$id = 102;
// connecting to database here
$sth = $dbh->prepare('SELECT * FROM users WHERE id = ?');
$sth->execute(array($id));
$num_rows = $sth->fetchColumn();
// if exist
if($num_rows){
// then fetch
while($end = $sth->fetch())
{
echo $end['id'];
}
}
But the output is blank, Why ?
It should be noted that the row with id = 102 is exist in the database.
As I understood, you have only one row with this ID. You can use fetch():
$id = 102;
// connecting to database here
$sth = $dbh->prepare('SELECT * FROM users WHERE id = ?');
$sth->execute(array($id));
$row = $sth->fetch();
// if record exist
if ($row) {
var_dump($row);
die();
}
PDO also have similar method rowCount but that would return effected rows in some cases.
Quoting from PHP Manual
For most databases, PDOStatement::rowCount() does not return the
number of rows affected by a SELECT statement. Instead, use
PDO::query() to issue a SELECT COUNT(*) statement with the same
predicates as your intended SELECT statement, then use
PDOStatement::fetchColumn() to retrieve the number of rows that will
be returned. Your application can then perform the correct action.
As suggested, you can query, count and proceed
$id = 102;
// connecting to database here
$sth = $dbh->prepare('SELECT COUNT(*) FROM users WHERE id = ?');
$sth->execute(array($id));
$num_rows = $sth->fetchColumn();
// if exist
if($num_rows > 0){
$sth = $dbh->prepare('SELECT * FROM users WHERE id = ?');
$sth->execute(array($id));
// then fetch
while($end = $sth->fetch())
{
echo $end['id'];
}
}

PHP PDO - incremental for loop that fetches the next array row with each loop

I'm in the process of updating my old mysql database techniques to prepared pdo statements. I'm all good with while loops while($row = $result->fetch()) however how would I do the following with PDO prepared statements?
$sql = "SELECT * FROM table WHERE id=".$id;
$result = mysql_query($sql) or die(mysql_error());
$loop_count = mysql_num_rows($result);
for($row=0;$row<7 && $loop_count-->0;$row++)
{
// Get next row
$loop_row = mysql_fetch_array($result);
echo $loop_row['field'];
}
I've tried this but with no joy:
$result = $conn->prepare("SELECT * FROM table WHERE id= ?");
$result->execute(array($id));
$loop_count = $result->rowCount();
for($row=0;$row<7 && $loop_count-->0;$row++)
{
// Get next row
$loop_row = $result->fetch();
echo $loop_row['field'];
}
Thanks!
UPDATE: The reason for using a for loop instead of a while loop is the ability to paginate the results, otherwise I would just put LIMIT 7 on the end of the SQL query.
To properly count rows with PDO you have to do this -
$result = $conn->prepare("SELECT * FROM table WHERE id= ?");
$result->execute(array($id));
$rows = $result->fetch(PDO::FETCH_NUM);
echo $rows[0];
But you would be better off using LIMIT in your query if all you want to do is get a static number of results.
In addition you're making your loop overly complex, there is no need to test for a range in the for condition just set the static number unless you're doing something weird, like possibly pagination.
You can try it this way:
$result = $conn->prepare("SELECT * FROM table WHERE id= ?");
$result->execute(array($id));
$loop_rows = $result->fetchAll();
$loop_count = count($loop_rows);
for($row=0;$row<7 && $loop_count-->0;$row++)
{
// Get next row
echo $loop_rows[$row]['field'];
}
As requested by the OP, here's an example of PDO prepared statements using LIMIT and OFFSET for pagination purposes. Please note i prefer to use bindValue() rather than passing parameters to execute(), but this is personal preference.
$pagesize = 7; //put this into a configuration file
$pagenumber = 3; // NOTE: ZERO BASED. First page is nr. 0.
//You get this from the $_REQUEST (aka: GET or POST)
$result = $conn->prepare("SELECT *
FROM table
WHERE id= :id
LIMIT :pagesize
OFFSET :offset");
$result->bindValue(':id', $id);
$result->bindValue(':pagesize', $pagesize);
$result->bindValue(':offset', $pagesize * $pagenumber);
$result->execute();
$rows = $result->fetchAll(PDO::FETCH_ASSOC);
This gives you the complete resultset of rows, limited to your required page. You need another query to calculate the total number of rows, of course.
What you could try is:
//Get your page number for example 2
$pagenum = 2;
//Calculate the offset
$offset = 7 * $pagenum;
//Create array
$data = array();
$result = $conn->prepare("SELECT * FROM table WHERE id= ? LIMIT 7 OFFSET ?");
$result->bind_param("ii", $id,$offset);
$result->execute();
$resultSet = $result->get_result();
while ($item = $resultSet->fetch_assoc())
{
$data[] = $item;
}
$result->close();
//echo resultSet you want
var_dump($data);

SQL only retrieve first item in the database

$search = mysql_query("SELECT subject FROM book WHERE useid = $userid") or die(mysql_error());
$sub = mysql_fetch_array($search, MYSQL_ASSOC);
print_r($sub);
There's a lot of subject in the book table with same user id, but it only retrieve first of it, why is that so?
mysql_fetch_array returns array representation of current row only:
Fetch a result row as an associative array, a numeric array, or both
You have to use loop to iterate over all returned rows:
$search = mysql_query("SELECT subject FROM book WHERE useid = $userid") or die(mysql_error());
while($sub = mysql_fetch_array($search, MYSQL_ASSOC)) {
print_r($sub);
}
You have to parse result of this
while($sub = mysql_fetch_array($search, MYSQL_ASSOC)){
print_r($sub);
}
Reason for this
mysql_fetch_array function returns an associative array, but it also returns FALSE if there are no more rows to return! Using a PHP While Loop we can use this information to our advantage.
If we place the statement "$row = mysql_fetch_array()" as our while loop's conditional statement we will accomplish two things:
We will get a new row of MySQL information that we can print out each time the while loop checks its conditional statement.
When there are no more rows the function will return FALSE causing the while loop to stop!
Hence it will continue to print data until the function returns false
As mysql* are officially depreciated you should be using mysqli* or prepared statements
//$Conn = new mysqli(host, username, pass, db);
$sqlquery = "SELECT subject FROM book WHERE useid = $userid";
//Execute the query reurns data into a $result
$result = $Conn->query($sqlquery);
//results into a associative array
$resultArray = $result->fetch_all(MYSQLI_ASSOC);
print_r($resultArray);
OR PDOStatement::fetchAll
<?php
$sth = $dbh->prepare("your query");
$sth->execute();
/* Fetch all of the remaining rows in the result set */
print("Fetch all of the remaining rows in the result set:\n");
$result = $sth->fetchAll();
print_r($result);
?>

PHP Zend - Execute to get a rowset and total number of records

I encounter some problem where i want to execute a SQL statement and get the total number of records + all the records.
$strSQL = "SELECT * FROM table WHERE ProjectID = 1 ";
$stmt = $db->query($strSQL);
$total = count($stmt->fetchAll());
while ($row = $stmt->fetch()){
..No More Record Shown here..
}
but there is no more record in the while loop after i execute fetchAll, i believe I need to get back to the first row or something, anyone know how to fix this?
You've already fetched all the records with fetchAll(). So when you call fetch(), there are no more records to read. Try storing the return value of fetchAll() in a variable and iterating through that. Something like this:
$strSQL = "SELECT * FROM table WHERE ProjectID = 1";
$stmt = $db->query($strSQL);
$allRows = $stmt->fetchAll();
$total = count($allRows);
foreach ($allRows as $row){
// process each $row
}

Categories