How to check if there are results with Prepared Statements - php

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);
?>

Related

how to echo out every item in table using PDO?

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.

PDO rowCount return -1

I use the pdo connection to access a sybase database.
when using rowCount the result is -1
$stmt = $dbh->prepare("select .... FROM users u WHERE u.ds_username like '%user%' order by ds_username ASC");
$stmt->execute();
$count = $stmt->rowCount();
As per the rowCount documentation,
PDOStatement::rowCount() returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement executed by the corresponding PDOStatement object.
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.
and
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.
Example
<?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;
?>

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 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.

PDO: Does fetchColumn moves the pointer of the returned results set?

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)
{
...
}
}
}
}
}

Categories