Check PDO query for result and then reuse the data - php

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!

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

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() );
}

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();
}

Related

Pulling Queries from Database Clears Results on Error vs. Stopping

We have a script that pulls queries from a database every couple of minutes. Those results are then shown in a table on a webpage. It works great, until that database responds with an error code (for whatever reason that may be) and instead of stopping it clears all the data. We don't want this data being cleared. It just needs to stop trying to pull if it gets an error message and wait until the next pull. Any idea how we can prevent this clearing all content?
Connection to Database:
<?php
$constr = 'mysql:host=mysql.test.com;dbname=test_custom;charset=utf8';
$dbUser = 'test';
$dbPW = 'test';
try {
$db = new PDO($constr, $dbUser, $dbPW);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
//$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$rez = "Connected";
//echo $rez;
} catch(PDOException $ex) {
$rez = "An Error occured connecting to the DB: ".$ex->getMessage().".";
//echo $rez;
}
?>
Code to display the results on the page:
<?php
include 'db.connect.php';
$sql = "SELECT ts_id, position, name FROM ts_applications WHERE enable = 1 ORDER BY Client";
$stmt = $db->prepare($sql);
$stmt->execute();
$num_rows = $stmt->rowCount();
//echo $num_rows;
if($num_rows > 0) {
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$id = $row['ts_id'];
$name = $row['name'];
echo "<tr>";
echo "<th><a href='position.php?id=" . $id . "'>" . $name . "</a></th>";
echo "</tr>";
}
} else {
echo "<tr>";
echo "<th>Please <a href='contact.php'>Contact</a> Doh! Something went wrong</th>";
echo "</tr>";
}
include 'db.close.php';
?>
Thank you in advance!
You might try changing your query to:
$sql = "IF EXISTS (SELECT TOP 1 fm_id FROM mb_searches WHERE fm_id IS NOT NULL) SELECT fm_id, position, client, city, state FROM mb_searches WHERE enable = 1 ORDER BY Client";
I don't know if that will filter out your error message

var_dump and print_r show nothing, can't check it item exists in Database

I have a PDO that is querying a non-existant user in the database to handle user registration. The problem is, var_dump and print_r both do not print anything if the user is not found.
try {
$stmt->execute();
while($row = $stmt->fetch()) {
var_dump($row);
print_r($row);
if($row = null) { // Not working
# if(!isset($row)) { // Not working
# if(empty($row)) { // Also not working
echo "User not found";
} else {
echo $row['realname']."<br>";
}
}
} catch(PDOException $e) {
echo "FATAL ERROR OCCURED:".$e->getMessage();
}
What is happening here? The page is just blank.
php -l index.php repors no syntax errors and the page is not throwing error 500.
Nothing in view source either.
Here is connection details:
try {
$dbh = new PDO('mysql:host=127.0.0.1;dbname=PHP_PDO', "root", "root", array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
));
} catch(PDOException $e) {
die("FATAL ERROR OCCURED");
}
$stmt = $dbh->prepare("SELECT realname FROM users WHERE name = :name" );
$stmt->bindParam(":name", $name);
$name = "mivuckovaca"; // NOT IN DATA BASE
The reason why it's not working, is that you are "assigning" in if($row = null) using 1 equal sign, rather than "comparing" if($row == null) with 2 equal signs (or 3 "if identical", depending on what you want to check for).
Consult: The 3 different equals here on Stack about this.
References:
http://php.net/manual/en/language.operators.assignment.php
http://php.net/manual/en/language.operators.comparison.php
PHP sees the "assignment" as being valid syntax and that is why you are not receiving any errors.
Turns out i had to reorganize the code a bit.
I took the $row = $stmt->fetch(); out of the while loop, and checked the $row seperately. Like this:
$stmt = $dbh->prepare("SELECT realname FROM users WHERE name = :name" );
$stmt->bindParam(":name", $name);
$name = "mivuckovaca"; // NOT IN DATABSE ON PURPOSE
try {
$stmt->execute();
} catch(PDOException $e) {
echo "FATAL ERROR OCCURED:".$e->getMessage();
}
$res = $stmt->fetchAll(); # Replaced fetch() with fetchAll()
if(empty($res)) {
echo "User not found";
} else {
foreach($res as $row) { # replaced while() with foreach()
echo $row['realname'];
}
}

Fetch specific column value from result set in php

MY code is:
try
{
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $user, $pass);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $conn->prepare("select userid,fname,type from native_users where email=:email and pass=:pass");
$stmt->bindParam(':email', $username);
$stmt->bindParam(':pass', $password);
$stmt->execute();
if($stmt->rowCount() > 0)
{
$_SESSION['uid']=$stmt->fetchColumn(0); //working
$_SESSION['fname']=$stmt->fetchColumn(1); //not working
$utype=$stmt->fetchColumn(3); // not working
if($utype == "admin")
{
// send to admin page
}
else
{
//send to user page
}
}
else
{
echo"Incorrect data.";
}
}
catch(PDOException $e)
{
echo "Error: " . $e->getMessage();
}
$conn = null;
I am new to PHP, I basically do Java.
I read here that:
There is no way to return another column from the same row if you use
PDOStatement::fetchColumn() to retrieve data.
In java, there is ResultSet#getString() funtion to do this.
What is the PHP equivalent of this?
You can use:
$result = $sth->fetch();
$result[0] will give userid
$result[1] will give fname
$result[2] will give type
Please read this
fetchColumn(), Returns a single column from the next row of a result
set.
Please read this for detail.
Use PDO::fetchAll() :
$rows = $stmt->fetchAll();
foreach ($rows as $v) {
echo $v['userid'] . " " . $v['fname'] . " " . $v['type'] ;
}
}
or just print_r($rows) you will notice that it's an associative array.

php trying to return the number of rows in a sql table

Trying to return the total row count for a sql table. My code returns the number of rows that are added not the total number of rows in the table. Any suggestions?
PHP:
require(ROOT_PATH . "inc/database.php");
try {
$query = $db->prepare("REPLACE INTO launch_email VALUES ('$email')");
$query->execute();
$count = $query->rowCount();
echo $count;
} catch (Exception $e) {
echo "Data could not be submitted to the database.";
exit;
rowCount() ist not a direct method of the PDO class, it is a method from PDOStatement.
Syntax:
public int PDOStatement::rowCount ( void )
Example based on your approach:
try {
$query = $db->prepare("REPLACE INTO launch_email VALUES ('$email')");
$query->execute();
$count = $query->rowCount();
} catch (Exception $e) {
...
PDO::exec returns the number of affected rows.
So you don't need to use rwoCount(), and note rowCount() is the method from PDOStatement.
require(ROOT_PATH . "inc/database.php");
try {
$count = $db->exec("REPLACE INTO launch_email VALUES ('$email')");
} catch (Exception $e) {
echo "Data could not be submitted to the database.";
exit;
}

PHP PDO prepared query won't return results from for loop

I have the following code:
$link = new PDO("mysql:dbname=$databasename;host=127.0.0.1",$username,$password);
$query = $link->prepare("SELECT * FROM index WHERE sbeid=:idvar");
for($j = 1; $j < count($array); $j++)
{
if($array[$j][16] == "TRUE" || $array[$j][16] == "FALSE")
{
$paramforquery = $array[$j][25];
$query->bindParam(":idvar",$paramforquery);
$query->execute();
$result = $query->fetchAll();
//do things with the $result
$query->closeCursor();
}
//else if, do stuff
}
$link = null;
$array is a large array composed of input from a CSV file that successfully loads via fopen().
My problem is this: the query just doesn't work. I know for a fact (ran the query directly on the server with some sample values from the file) that the data is in the database, but when i var_dump the $results each time the for loop runs, I just get an empty array.
What am I doing wrong?
TIA.
Increase the error reporting - the standard advice.
Set the error mode of the pdo object to ERRMODE_EXCEPTION - you hardly can miss an error that way.
Use a debugger or add some debug output to your script - a real debugger is way better.
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
$array = foo();
echo '<pre>Debug: |array|=', count($array), '</pre>';
$link = new PDO("mysql:dbname=$databasename;host=127.0.0.1",$username,$password);
$link->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$query = $link->prepare("SELECT * FROM index WHERE sbeid=:idvar");
$query->bindParam(":idvar", $paramforquery);
foreach($array as $row) {
echo '<pre>Debug: row[16]='; var_dump($row[16]); echo '</pre>';
if($row[16] == "TRUE" || $row[16] == "FALSE") {
$paramforquery = $row[25];
echo '<pre>Debug: paramforquery='; var_dump($paramforquery); echo '</pre>';
$query->execute();
echo '<pre>Debug: rowcount='; var_dump($query->rowCount()); echo '</pre>';
$result = $query->fetchAll();
//do things with the $result
$query->closeCursor();
}
//else if, do stuff
}
$link = null;
Are you sure you are getting a connection ?
try {
$link = new PDO("mysql:dbname=$databasename;host=127.0.0.1",$username,$password);
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
}
This will catch any exceptions from trying to connect. If this works ok, try putting the query under the $link line and see what's returned.
If your query runs manually, i'd say its something to do with your DB connection. Make sure you've got error reporting turned on.
Additional:
In your query you have this :idvar ? Shouldnt you be using a PHP variable like this $idvar.
so
$query = $link->prepare("SELECT * FROM index WHERE sbeid=" . $idvar);

Categories