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);
Related
I thought I could use MYSQLI_STMT_NUM_ROWS and MYSQLI_STMT_STORE_RESULTto check for no. of rows returned. (see commented lines ///1///, ///2///, ///3///)
But it doesn't seem to in the context below.
This codes does work (without the commented lines), but I am trying to add an extra check, to confirm that no more than 1 record is returned. (even though this should always be the case, as the email field in the table is unique, but it doesn't hurt to do the check anyway).
Can anyone shed some light on what I'm doing wrong?
This is the error I get below (line 86 if the WHILE ... line):
An error occurred in script 'L:\includes\login_functions.inc.php' on line 86: mysqli_fetch_array() expects parameter 1 to be mysqli_result, boolean given
NOTE:
This a stripped down version of the original code.
$form_email and $form_pass are originated from form input.
Code is procedural, because I like it that way.
<?php
// Prepared statement.
$prep_sel = 'SELECT user_id, first_name, user_level, pass FROM users WHERE email=? and active is null';
// Initialise connection.
$stmt_sel = mysqli_stmt_init($dbc);
// Check if there are any DB connection problems.
....
// Prepare statement, bind parameters (an integer and a string) and execute the statement
if (mysqli_stmt_prepare($stmt_sel, $prep_sel)) {
mysqli_stmt_bind_param($stmt_sel, 's', $form_email);
mysqli_stmt_execute($stmt_sel);
///1///mysqli_stmt_store_result($stmt_sel);
}
///2///if (mysqli_stmt_num_rows($stmt_sel) == 1) { // one record found.
// Get the results.
$result = mysqli_stmt_get_result($stmt_sel);
while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
// Now check if the passwords match.
if (password_verify($form_pass, $row['pass'])) {
return array(true, $row);
} else {
$errors[] = 'the details you provided does not match our records';
$errors[] = 'your account has not been activated';
}
}
///3///}
/* close statement */
mysqli_stmt_close($stmt_sel);
?>
After calling mysqli_stmt_store_result(), the MySQL driver will not permit you to operate on a result set until all rows are fetched or the result set is freed and the statement closed. So a subsequent call to mysqli_stmt_get_result() will return false, and probably result in an error like
Commands out of sync; you can't run this command now
which you may check with echo mysqli_error($dbc);
Transferring the statement's result set with mysqli_stmt_get_result() will give you access to its num_rows property, so you actually don't need to use mysqli_stmt_store_result(). Instead just rely on mysqli_stmt_get_result() before checking the number of rows returned:
if (mysqli_stmt_prepare($stmt_sel, $prep_sel)) {
mysqli_stmt_bind_param($stmt_sel, 's', $form_email);
mysqli_stmt_execute($stmt_sel);
// Transfer the result set here:
$result = mysqli_stmt_get_result($stmt_sel);
// Then check rows returned on the $result obj
// using mysqli_num_rows(), not mysqli_stmt_num_rows()
if (mysqli_num_rows($result) == 1) {
while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
// Check your password, etc....
}
}
else {
// More than 1, do whatever you need to handle this
}
// Close it
mysqli_stmt_close($stmt_sel);
}
function authenticateUser($email, $password){
$stmt = $db->prepare("SELECT user_id, first_name, user_level, pass FROM users WHERE email=? and active is null");
$stmt->bind_param('s', $email);
$stmt->execute();
$res = $stmt->get_result();
if($res->num_rows > 0){
$hash = $res->fetch_object()->pass;
if(password_verify($password, $hash)){
return true;
}
}
return false;
}
call the function
if(authenticateUser($_POST['email'], $_POST['password'])){
//do something
}
else{
echo "Invalid Email/Password";
}
Consider the following code:
$conn = new PDO("connection string", "user name", "password");
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "SELECT `id` FROM `users` WHERE `displayname` = :displayname";
$parms = array(':displayname' => 'Test');
$stmt = $conn->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$stmt->execute($parms);
$res = $stmt->fetch();
echo $res == null;
and more specifically consider this line: echo ($res == null);
If there is no row in the database that matches the echo displays a value of 1 -as expected -because the $res is in fact null. However, if there is a result returned from $stmt->fetch(); the echo produces nothing. But, I would have expected it to have produced a 0 because the value of $res is an array.
How can I consistently and concisely compare the result to simply determine if there was a result or not?
When there's no result, it doesn't return null. It returns false (well, assuming PDO::FETCH_BOTH -- to see a full list, read the doc). Also, false casted to a string is an empty string. That's why you're not getting any output.
echo false; //Outputs nothing
$s = (string) false;
var_dump($s === ""); //true
As for determining whether or not you have a result, you can just do a simple implicit check:
$res = $stmt->fetch();
if ($res) {
echo 'Got a row!';
} else {
echo 'No row :(';
}
This works because of a few implicit casts. Consider what fetch is going to return: either a non-empty array, or false. (bool) $arr === true only if count($arr) > 0. From here, you should be able to see why this works.
(Note: in theory, the result set could indeed be an empty row. This would cause fetch to return an emtpy array. That would break the implicit comparison as it would then be considered false. I can't imagine this would actually ever happen though. I can't think of a statement that would return a result set with a row that has no columns.)
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);
}
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.
I've got:
mysql_connect($host,$username,$password);
#mysql_select_db("db") or die("Error: Cannot select database");
$query = "select password from users where name = '".$_POST['login-userid']."'";
$result = mysql_query($query);
if ($result == false) {
echo "Invalid username or password";
} else {
if (mysql_result($result,0) == hash('sha256', $_POST['login-password'])) {
echo "Logging in...";
}
}
For some reason I keep getting an error for the mysql_result line, even when it shouldn't be executed (when the username doesn't exist, ie $result evaluates to false).
mysql_query will only return false if there is an error. In this case there is no error, there are just 0 rows.
You need to use mysql_num_rows to get the number of rows returned.
You can var_dump($result) and see the value, if it's a resource (according to php), then your query was successful, if not false is returned. It's a boolean false but your == should still be respected if indeed false was returned.
mysql_query($query);
returns the result set of your query. It does not return true or false.
You may use mysql_num_rows() to check if the result of the query exist such as:
if(mysql_num_rows($query)) {
// exist
} else {
// does not exist
}