Reputation: 51
I am new to PDO, and am in the process of upgrading an application from mysql_query to PDO. This is surely a stupid question - but I hope someone can help me wrap my head around it.
I need to see if a PDO query has any data: - if it doesn't, throw an error - if it does, retrieve that data
I could do this easily with mysql_num_rows, but that's deprecated as we all know.
The issue is that once I've checked if there is any data, I can no longer retrieve it.
The check runs fine, but then when trying to retrieve the actual result, it's empty. I can of course execute the query again after the check - but I'd rather avoid having to run a query twice.
try
{
$result = $pdo2->prepare("SELECT first_name FROM users WHERE email = :email;");
$result->bindValue(':email', $email);
$result->execute();
$data = $result->fetchAll();
}
catch (PDOException $e)
{
$error = 'Error fetching user: ' . $e->getMessage();
echo $error;
exit();
}
if (!$data) {
echo "No data!";
} else {
echo "Data found!";
}
$row = $result->fetch();
echo "First name: " . $row['first_name'];
How can I solve this? I tried to assign $result to another variable ($test = $result), and then run the data check on the $test variable instead - but even so, the $result variable STILL doesn't return any data after running the check (see the commented lines):
try
{
$result = $pdo2->prepare("SELECT first_name FROM users WHERE email = :email;");
$result->bindValue(':email', $email);
$result->execute();
$test = $result; // Duplicating the variable
$data = $test->fetchAll(); // Running the check on the duplicated variable
}
catch (PDOException $e)
{
$error = 'Error fetching user: ' . $e->getMessage();
echo $error;
exit();
}
if (!$data) {
echo "No data!";
} else {
echo "Data found!";
}
$row = $result->fetch(); // Still doesn't return the result!
echo "First name: " . $row['first_name'];
This is really doing my head in... I think there's a simple solution somewhere, I just can't see it. Please help!
Upvotes: 1
Views: 1296
Reputation: 57121
You can always fetch individual rows and for the first row, check if the data is returned and process if not. Then enter a do...while()
loop which processes the data and then reads the next row at the end of the loop...
try
{
$result = $pdo2->prepare("SELECT first_name FROM users WHERE email = :email;");
$result->bindValue(':email', $email);
$result->execute();
$row = $result->fetch(); // Fetch first row of data
if (!$row) {
echo "No data!";
} else {
echo "Data found!";
do {
echo "First name: " . $row['first_name'];
}
while ($row = $result->fetch());
}
}
catch (PDOException $e)
{
$error = 'Error fetching user: ' . $e->getMessage();
echo $error;
exit();
}
Upvotes: 0
Reputation: 781068
$result->fetch()
only fetches rows that haven't already been fetched. Since you fetched everything with $result->fetchAll()
, there's nothing left.
If you want the first row, you can use:
$row = data[0];
If you want to process all the rows, use:
foreach ($data as $row)
Instead of fetching everything, you can use the rowCount()
method.
if (!$result->rowCount()) {
echo "No data";
} else {
echo "Data found!";
}
There are caveats regarding the use of rowCount()
with SELECT
queries in PDO, but I think it generally works with MySQL.
Upvotes: 2
Reputation: 33813
As you are using a try/catch
block you can raise your own exceptions as well as catch those thrown by PDO - so you could do something like this:
try{
$sql='SELECT first_name FROM users WHERE email = :email;';
$stmt = $pdo2->prepare( $sql );
if( !$stmt )throw new Exception('Failed to prepare sql statement');
$result=$stmt->execute( array( ':email' => $email ) );
if( !$result )throw new Exception('Failed to get any results');
$rows = $stmt->rowCount();
if( $rows == 0 )throw new Exception('Empty recordset');
while( $rs=$stmt->fetch( PDO::FETCH_OBJ ) ){
echo $rs->firstname;
}
}catch ( PDOException $e ){
exit( 'Error fetching user: ' . $e->getMessage() );
}
Upvotes: 0