I've used PDO in my PHP application. But I have problem with fetch() function. Whenever I count the result of fetch(), it tells me there is something in resultset. But when I want to show them, it has nothing to show.
try
{
$sql = "SELECT id,salt FROM tbl_admin WHERE username = ? AND password = ? LIMIT 1";
$q = $db->prepare($sql);
$q->execute(array($username,$password));
$rows = $q->columnCount();
if ($rows > 0)
{
$r = $q->fetch(PDO::FETCH_BOTH);
echo(count($r).'<br />'); // Prints 1
print_r($r); // Nothing to print ...
die();
}
else
{
die('error');
}
}
catch(PDOException $e)
{
echo $e->getMessage();
}
May you help me please?
You're counting the number of columns, not the number of rows.
$rows = $q->columnCount();
This should be
$rows = $q->rowCount();
That said, rowCount is for UPDATE, INSERT, or DELETE queries. So that isn't the problem here.
Firstly should also be checking if $q->execute returns true or false.
Secondly you should be checking if $q->fetch returns true or false.
Given your code
$r = $q->fetch(PDO::FETCH_BOTH);
echo(count($r).'<br />'); // Prints 1
Try the following.
echo(count(false));
You'll notice that this also outputs 1.
So the solution is, that you need to check the return value of $q->fetch before assuming it returned a valid row.
Related
The problem I am having is that it always returns true no matter if the username passed in is valid or not.
$data = array($_POST["username"]);
$db = new PDO('mysql:host=localhost;dbname=Example;charset=utf8', 'Example', 'Example');
$stmt = $db->prepare("SELECT * FROM Table WHERE username=?");
$num_rows = $stmt->execute($data);
if($num_rows>0){
echo "true";
}
else{
echo "false";
}
$stmt->execute($data) returns TRUE on success.
If you want to get the number of rows returned, you need to use fetchAll after the execute
USE SQL FUNCTIONS
SELECT COUNT(*) as uCount FROM Table WHERE username=? // you can change * to id, for example.
then check if($data['uCount'] > 0)
You can change your SQL statement a little bit and capture either true or false in return as query result.
SELECT count(username) > 0 as user_exists FROM Table WHERE username=?
Read the query result to find if it is true or false.
PDOStatement::execute() returns a boolean to indicate success; if you're using exception error handling it will always return true or throw an exception (recommended by yours truly).
You can fetch the results (assuming there's only one) like this:
if (($data = current($stmt->fetchAll(PDO::FETCH_ASSOC)) !== false) {
echo "yay";
// do stuff with $data
} else {
echo "sorry dude";
}
The use of current() returns the first element of the returned result set or false if there was none.
Update
If you only need to return true or false, it's better to do just this:
$stmt = $db->prepare("SELECT COUNT(*) FROM Table WHERE username=?");
if ($stmt->execute($data) && current($stmt->fetchAll(PDO::FETCH_COLUMN))) {
echo 'true';
} else {
echo 'false';
}
try this
$num_rows = $stmt->fetch(PDO::FETCH_NUM);
This is not dieing as I expected it to, if $key is not a value in the key_code column of the database. Instead it just continues. I'm probably missing something really simple.
$key = $_GET['k'];
$keycheck = mysql_query("SELECT * FROM ib_dist WHERE key_code = '$key'");
if (!$keycheck) {
die("A database error has occured.");
} else {
mysql_query returns a resource or false based on whether the query executed successfully. It does not in any way denote how many rows were returned or whether the query did anything, only whether it executed successfully.
Check how many results where returned or evaluate the returned result separately.
try checking the amount of rows found.
$key = $_GET['k'];
$result = mysql_query("SELECT * FROM ib_dist WHERE key_code = '$key'");
if (!$result) {
die("A database error has occured.");
} else if (0 == mysql_num_rows($result)) {
// unknown key action
} else {
// known key action
}
I was wondering, what is the best way to count the rows of a table with PHP using PDO?
Here is what I have, but not getting anything for $count.
$count = $con -> query("SELECT COUNT(*) FROM item_descr")->fetch(PDO::FETCH_NUM);
echo $count[0];
if (count($count)>0)
{
$subStatus = "The email introduced is already in our database.";
}
There's no reason to use the PHP count() function on the array returned by fetch(). The count has already been calculated in SQL, so you want the value stored in the result, not the count of results.
Here's how I would write it:
$countStmt = $con->query("SELECT COUNT(*) FROM item_descr");
if ($countStmt === false) {
// do something to report the error
}
$count = 0;
while ($row = $countStmt->fetch(PDO::FETCH_NUM)) {
$count = $row[0];
}
if ($count > 0)
{
$subStatus = "The email introduced is already in our database.";
}
Always check that the return value from query() is a valid PDOStatement. Any error causes it to return false, and the scalar value false is not an object with a fetch() method.
In other words, you can't make the call in a fluent interface manner ($con->query()->fetch()), because query() is not guaranteed to return an object.
$count = $con->query("SELECT COUNT(*) as `num` FROM `item_descr`")
->fetch(PDO::FETCH_ASSOC);
echo $count['num'];
if ( $count['num'] > 0 )
{
$subStatus = "The email introduced is already in our database.";
}
would work.
If you do a COUNT in your query, you will ALWAYS have just ONE result, namely the number of rows. So count( $result) will always give you 1. In my example I use the COUNT from the query.
I have this PHP function that gets the data of the currently logged in user, or returns false if the visitor either isn't logged in, or has invalid user_id and password_hash cookies. For some reason, $q->fetch() always returns FALSE.
if( $_COOKIE['cuid']!='' && $_COOKIE['cuph']!='' )
{
try
{
$q = $db->prepare( 'SELECT * FROM users WHERE user_id = ? AND password = ?' );
$data = array( $_COOKIE['cuid'], $_COOKIE['cuph'] ); // id and password hash
$q->execute($data);
$num = count( $q->fetchAll() ); // in my case, $num is set to 1
if( $num == 1 )
{
$q->setFetchMode(PDO::FETCH_CLASS, 'User');
$user = $q->fetch(); // $user is set to FALSE for some reason
return $user;
} else {
return FALSE;
}
}
catch( Exception $e )
{
$db->rollBack();
echo 'Error: ' . $e->getMessage();
}
} else {
return FALSE;
}
Running that with exact data instead of placeholders in the query doesn't change anything, and running that query directly in my database returns 1 row, like it should. I checked, $num does indeed equal 1. I don't know why $q->fetch() returns FALSE, so any pointers would be very much appreciated.
You're already fetching all results using fetchAll(). The result set is thereby exhausted, you cannot fetch any more results from it. You simply want $q->rowCount() to count the rows or save the array returned by fetchAll() somewhere and use it later.
As said, you cannot use fetchAll then fetch after one query; but rowCount cannot be used for select. A solution can be:
You get results in an array with fetchAll:
$results=$q->fetchAll()
Then you can get and use or check the number, for example:
echo count( $results);
And get and work with results, for example:
foreach ($results as $result)
{
var_dump($result);
}
function procLogin($username,$password){
$query = "SELECT *
FROM members
WHERE login = '".mysql_escape_string($username)."'
AND passwd = '".mysql_escape_string($password)."'";
$result = mysql_query($query);
//$values = array();
while($row = mysql_fetch_array($result))
{
return 'gg';
return(array($row['member_id']));
}
}
Not able to get the userlevel field.... nor anything....
Not sure exactly what your question is, but one problem is that you're returning from within this while loop:
while($row = mysql_fetch_array($result))
{
return 'gg';
return(array($row['member_id']));
}
In fact, you're returning twice from within the loop... so the procLogin() function will always return a value of "gg", unless something goes wrong with your SQL query.
In general, you should avoid return statements within any loop, as it creates confusion and can lead to unexpected results.
return(array($row['member_id']));
Looks wrong - it should be:
return($row['member_id']);
You shouldn't need to define the array in the return like that.
You also use mysql_fetch_array () which returns as a numerical index - the function you probably want is mysql_fetch_assoc which is much nicer to work with as it returns the values with the keys as the column name rather than a numerical index.
Here's it again with a few tidy ups:
function procLogin($username,$password){
$query = "SELECT *
FROM members
WHERE login = '".mysql_escape_string($username)."'
AND passwd = '".mysql_escape_string($password)."'";
$result = mysql_query($query);
$row = mysql_fetch_assoc($result);
if ($row['member_id'] > 0)
{
return ($row['member_id']);
}
else
{
return false;
}
}
I'm thinking, based on your comments about the userlevel, that you want to return the entire array rather than just the member_id ? Here's a slight edit to Meep3D's answer above:
function procLogin($username,$password){
$query = "SELECT *
FROM members
WHERE login = '".mysql_escape_string($username)."'
AND passwd = '".mysql_escape_string($password)."'";
$result = mysql_query($query);
$row = mysql_fetch_assoc($result);
if (mysql_num_rows($result) > 0)
{
$row = mysql_fetch_assoc($result);
return $row;
}
else
{
return false;
}
}
This should return an array of all your table columns, if you are looking for the userlevel, presumably you should be able to access it something like:
$loginInfo = procLogin("theband","password1");
//if ($loginInfo) or something similar here
$level = $loginInfo['userlevel'];
So are you getting anything returned? That is to say, is it actually going into the while loop?
I'd use a mysql_error() function call straight after the mysql_query call to see if anything went wrong there.
Maybe there was no connection made, for example.
Are you still having issues? If so try something like:
echo $query;
after you define the query, then copy+paste that into phpmyadmin to check if there are any valid returns from the database.
After that try placing:
if (mysql_error())
{
trigger_error ("MySQL Error: ". mysql_error(), E_USER_ERROR);
}
Just after you call mysql_query. This should trigger an error if there is one giving you details of what went wrong.