Find last loop of while($stmt->fetch()) - php

Is it possible to find when is the last loop of :
$stmt = $connection->stmt_init();
if ($stmt->prepare("SELECT `ProductId` FROM Products"))
{
$stmt->execute();
$stmt->bind_result($product_id);
while($stmt->fetch())
{
if ($lastloop)
{
echo 'The last id is -> ';
}
echo $product_id.'<br />';
}
}
I want to output something like :
1
2
...
9
The last id is -> 10

You could use $stmt->num_rows^, but ONLY if you $stmt->store_result() the result set and keep counting the active row offset. Storing the results is not viable for large sets.
Use SELECT SQL_CALC_FOUND_ROWS ProductId FROM Products; like in this answer here^. And then use FOUND_ROWS() to know the row number WITHOUT storing the result set initially. Requires one extra query... which is a small price to pay.
That's all you've got as viable and easy solutions.

You could keep count and compare to the number of rows
$stmt->store_result();
$rows = $stmt->num_rows;
$count = 1;
while( $stmt->fetch() ) {
if( $count == $rows ) {
echo 'The last id is -> ';
}
$count ++;
echo $product_id . '<br />';
}

Related

PHP check if there are no more results without using rowCount function

Normally to check count for the number of records being fetched from the database we use rowCount function while using PDO with PHP. However, I am stuck in a case where I want to have the same result to use in an if...else statement but I cannot use it and I will explain below with code example why.
Normal case:
$stmt = $pdo->prepare("SELECT * FROM table");
$stmt-> execute();
$count = $stmt->rowCount();
if($count > 0){
while($row = $stmt->fetch()){
// Perform a task....
}
}
Or, we also use SELECT COUNT(*) as cnt FROM table and then use fetch for the count element.
However, the problem in my case is I can't use these methods because they will return count value of the root query that was executed. And here I have an if condition which when satisfied loads the result and I want to count the total number of records satisfying that condition.
For example:
$stmt = $pdo->prepare("SELECT * FROM table");
$stmt-> execute();
while($row = $stmt->fetch()){
// Suppose I have a variable $distance which I calculated and based on that the result should appear
if($distance < 100){
// Display the records which satisfied this condition
// Once the records are fetched, NOW I WANT TO COUNT THEM under "this" condition.
// This count will be based on the condition above which will be different from the root count using `rowCount`
if($count == 0){
// Perform a task here
}
}
}
How to count the number of records that satisfies under the condition if($distance < 100)? Any help would be appreciated.
$count = 0;
while($row = $stmt->fetch()){
if($distance < 100){
$count++;
// display records
}
}
if($count == 0){
// Perform a task here
}
You can just count the records with your while loop as shown above. I am assuming you have done bind_result of $display. Outside of the loop, if you find count = 0, then perform your desired task.

Checking against the database for a record exist

I'm working on another class project and what I want to do is check the database is a row exists.
I've seen several different methods throughout the forum and not one of them seem to work. I've spent roughly 12 hours on this one thing and it's becoming a time sink.
Here is the last iteration of the code I've tried :
$ciid = $_POST['categoryid'];
$check = $db->prepare("SELECT categoryid, imgid FROM catType WHERE categoryid = $ciid AND imgid = $imgID ");
$check->bindParam(categoryid,$ciid);
$check->bindParam(imgid,$imgID);
$check->execute();
if($check->rowCount() > 0 ){
echo "dqowdhnoqwhd";
} else {
/*run working insert */
}
/* the form that passes the $_POST value */
echo "<p><input type=\"checkbox\" name=\"catname[]\" value=\"".$row['categoryid']."\" />" . $row['cName'] . " </p>";
echo "<p><input type=\"hidden\" name=\"".$imgID."\" value=\"".$imgID."\"/></p>";
As it stands now, I get no errors but it also doesn't tell me that the record is already in the database. When I add a new record , it just duplicates it.
the array :
Array
(
[catname] => Array
(
[0] => 1
)
[111] => 111
[icud] => update category
)
I ran the query in phpMyAdmin and the formula worked for what I wanted it to do.
Your code (e.g. bind_param() usage) suggests you want to use a paramaterized query, but you are not leaving any places in the query for the parameters you try to bind. Try this instead:
$ciid = $_POST['categoryid'];
$stmt = $db->prepare("SELECT COUNT(*) FROM catType WHERE categoryid = ? AND imgid = ?");
$stmt->execute(array($ciid, $imgID));
$count = $stmt->fetchColumn();
if($count > 0) {
echo "dqowdhnoqwhd";
} else {
/*run working insert */
}
Note from the documentation about numRows():
If the last SQL statement executed by the associated PDOStatement was a SELECT statement, some databases may return the number of rows returned by that statement. However, this behaviour is not guaranteed for all databases and should not be relied on for portable applications.
Instead, since you're not fetching anything useful from the database you can just do a COUNT() of the rows that match. The fetchColumn() function will pull the first column of the next row in the result set; handy for pulling a single value out.
What I didn't do was run a foreach loop on the array items that was holding the categoryid. So everything that I may have tried for the past , many hours wouldn't have worked. here is my solution, please feel free to suggest improvements
n = $_POST['catname'];
foreach($n as $row => $value){
$para = $value;
}
$param = $imgID;
$check = $db->prepare("SELECT imgid , categoryid FROM catType WHERE imgid = $param AND categoryid= $para");
$check->execute();
$count = $check->fetchColumn();
//echo var_dump($check);
if($count > 0) {
echo "Category already added";

PHP PDO Row Counting

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.

Is there a more efficient way to do this

function countBrand($brand_id, $brand_name) {
$sql = "SELECT brand FROM coupons WHERE expire >= CURRENT_DATE AND brand='".$brand_id."'";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
echo '<li>'.$brand_name.'</li>';
}
function brandCount() {
$sql = "SELECT DISTINCT brand,brand_id,brand_name FROM coupons,coupons_brand WHERE brand=brand_id AND expire >= CURRENT_DATE ORDER BY brand_name";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
$num = mysql_num_rows($result);
echo '<h3>'.$num.' Brands</h3>';
echo '<ul>';
$i = 0;
while ($i < $num) {
$brand_id = mysql_result($result, $i, "brand_id");
$brand_name = mysql_result($result, $i, "brand_name");
countBrand($brand_id, $brand_name);
$i++;
}
echo '</ul>';
}
It works perfectly and gives me the results I am looking for. I am not as strong with sql statements as I would like to be. Is there a way I could do this that would be more efficient, it seems very slow.
Basically, it counts how many brands have coupons, then coupons how many coupons each brand has..
I also, on the same page, do this for categories. There are a few thousand categories and maybe 20,000 coupons.
there are a few php optimisations you could do, but they probably wont save you much time, compared to adding an index to mysql on the correct columns
i have commented some php optimisations below, maybe of interest to you anyway
given the simple nature of the functions, it is not necessary to have 2 functions, and that would save the timecost of calling countBrand(), (although it is a pretty minimal time saving)
function countBrand($brand_id, $brand_name) {
$sql = "SELECT brand FROM coupons WHERE expire >= CURRENT_DATE AND brand='".$brand_id."'";
$result = mysql_query($sql) || die (mysql_error()); // always check for errors
list($brand) = mysql_fetch_row($result);
// fetch row, returns a more concise array then mysql_fetch_array
// $row = mysql_fetch_array($result);
// use commas rather then . when concatenating echo statements
// dots force concatenation before output
echo '<li>',$brand,'</li>';
}
function brandCount() {
$sql = "SELECT DISTINCT brand,brand_id,brand_name FROM coupons,coupons_brand WHERE brand=brand_id AND expire >= CURRENT_DATE ORDER BY brand_name";
$result = mysql_query($sql) || die(mysql_error()); // always check for errors
// $row = mysql_fetch_array($result); // not sure why this is needed
$num = mysql_num_rows($result);
// use commas rather then . when concatenating echo statements
// dots force concatenation before output
echo '<h3>',$num,' Brands</h3>';
echo '<ul>';
// fetch all cols at once, rather then using lots of separate calls to mysql_result
// use mysql_fetch_row as it returns just the ordered values (vs mysql_fetch_assoc, and mysql_fetch_array)
//
while(list($brand, $brand_id, $brand_name) == mysql_fetch_row($result)) {
countBrand($brand_id, $brand_name);
}
// replaced with while loop above
// $i = 0;
// while ($i < $num) {
// $brand_id = mysql_result($result, $i, "brand_id");
// $brand_name = mysql_result($result, $i, "brand_name");
// countBrand($brand_id, $brand_name);
// $i++;
}
echo '</ul>';
}
those enhancements will only give you a minor speed increase
the biggest speed increase you will get is if you call the database less.
currently you select each brand, and then go back and count each brand individually
without knowing the structure of you tables this sql is difficult for me to write, so it is a guess, but it should point you in the right direction
SELECT brand, brand_id, brand_name, COUNT(*) as brandcount
FROM coupons
JOIN coupons_brand ON brand=brand_id
WHERE expire >= CURRENT_DATE
GROUP BY brand, brand_id, brand_name
ORDER BY brand_name
mysql_fetch_array($result,MYSQL_ASSOC);
SELECT SQL_CACHE brand FROM
Profiling query

Select statement within a while statement

First, I coded this, which looks inside a table, gets the last 10 entries, and displays them. The output is as expected, a list of the 10 last entries in the database.
$query = "SELECT dfid FROM downloads_downloads ORDER BY did DESC limit 10";
$dlresult = mysql_query( $query );
$i=0;
$num = mysql_num_rows ($dlresult);
while ($i < $num) {
$dfid= mysql_result($dlresult,$i,"dfid");
echo "<b>filenumber:</b> $dfid <br>";
++$i;
}
But I don't just need the filenumber. I need the actual filename and url from another table. So I added a select statement inside the while statement, using the file number.
But for some reason, this code only displays one filename instead of 10. I know, from the above code, it's getting all 10 file numbers.
$query = "SELECT dfid FROM downloads_downloads ORDER BY did DESC limit 10";
$dlresult = mysql_query( $query );
$i=0;
$num = mysql_num_rows ($dlresult);
while ($i < $num) {
$dfid= mysql_result($dlresult,$i,"dfid");
$query2 = "SELECT file_name, file_name_furl FROM downloads_files WHERE file_id = '$dfid'";
$dlresult2 = mysql_query( $query2 );
$dlfile_name= mysql_result($dlresult2,$i,"file_name");
$dlfile_name_furl= mysql_result($dlresult2,$i,"file_name_furl");
echo "filenumber: $dfid <br>"; //Shows 10, as expected.
echo "filename: $dlfile_name - $dlfile_name_furl <br>"; //Shows only 1?
++$i;
}
I can manually execute the sql statement and retrieve the file_name and file_name_furl from the table. So the data is right. PHP isn't liking the select within the while statement?
Looks like you're only going to ever have 1 row, in your 2nd select statement, because you are just selecting one row, with your where statement.
So, you're only going to ever have row 0 in the 2nd statement, so its only finding row 0 on the first loop. try instead:
$dlfile_name= mysql_result($dlresult2,0,"file_name");
$dlfile_name_furl= mysql_result($dlresult2,0,"file_name_furl");
However, insrtead of making 11 separate queries, try using just one:
$link = new mysqli(1,2,3,4);
$query = "SELECT downloads_downloads.dfid, downloads_files.file_name, downloads_files.file_name_furl FROM downloads_downloads LEFT OUTER JOIN downloads_files ON downloads_files.file_id = downloads_downloads.dfid ORDER BY downloads_downloads.dfid DESC limit 10;
$result = $link->query($query) ;
if((isset($result->num_rows)) && ($result->num_rows != '')) {
while ($row = $result->fetch_assoc()) {
echo "filenumber: $row['dfid'] <br>";
echo "filename: $row['file_name'] - $row['file_name_furl'] <br>";
}
Read up on mysql joins http://www.keithjbrown.co.uk/vworks/mysql/mysql_p5.php
I'm not sure if this is syntax correct, but it gives you the right idea =)

Categories