Reputation: 10408
This is driving me nuts, I have a login function that checks to make sure that the users credentials are correct, and also checks to see if an 'activation' field for that user is empty (if it wasn't, it means that they haven't activated yet and therefore shouldn't be able to log in). If all of those conditions check out fine, it returns a user id in a variable, and if not it returns false
.
The function runs correctly right up until I add the if statement that checks if the variable $activation
is empty, using empty()
. If the field is truly empty, it returns the user_id like it's supposed to, but if the field isn't empty and still contains the 40 char activation code - it also lets the user log in. Which is ridiculous.
Here is the login function (with irrelevant portions removed):
function loginCheck($email, $password) {
$stmt = $dbh->prepare("SELECT `salt`,`activation` FROM `users` WHERE `email`= :email LIMIT 1");
$stmt->bindParam(':email', $email);
$stmt->execute();
if ($stmt->rowCount() == 1) {
$salt = $stmt->fetchColumn(0);
$activation = $stmt->fetchColumn(1);
if (empty($activation)) {
// another few unrelated tasks and query here to grab user id which is returned below
if ($stmt->execute()) {
return $stmt->fetchColumn(1); // the returned user ID
} else {
return false;
}
} else {
return false; // It should return this false here because the field IS NOT empty!
}
} else {
return false;
}
}
1) I have performed the first query manually, and it does in fact select the fields salt
and activation
flawlessly.
2) I have checked to make sure that the column being fetched and applied to the var $activation
is correct, it is the second column so $activation = $stmt->fetchColumn(1)
is fine.
Now on the login.php
page which calls the above function, here is the code relating to calling the function and logging in:
$login = loginCheck($email, $password);
if ($login === false) {
$errors[] = 'Unable to log you in';
}
if (!empty($errors)) {
foreach ($errors as $error) {
echo $error, '<br />';
}
} else {
$_SESSION['user_id'] = $login;
header('Location: you/default.php');
exit();
}
I've looked and looked and can't find any errors. Why on earth is this occurring?
The activation field in my MySQL table is set to varchar(40)
with a collation of utf8_general_ci
, and since the activation field is populated with numbers and letters, I'm assuming it's a string.
And yes, the user_id that is returned is the one that relates to the user logging in, so that is correct.
Upvotes: 1
Views: 917
Reputation: 1659
As you can see here: http://php.net/manual/en/pdostatement.fetchcolumn.php,
There is no way to return another column from the same row if you use PDOStatement::fetchColumn() to retrieve data.
This is because each time you call fetchColumn it will apply over the row next to the row on which the previous call applied.
$salt = $stmt->fetchColumn(0);
$activation = $stmt->fetchColumn(1);
The second call to fetchColumn() is working over the row next to that of the first call. In your case, as there is only one row, fetchColumn() returns NULL, so that's why activation appears as empty.
Use fetch() to retrieve an array with all the values of the row:
$row=$stmt->fetch();
$salt=$row[0];
$activation=$row[1];
Upvotes: 4
Reputation: 4592
Consider this approach..
Columns
`activation_code` varchar(40) not null,
`activated` tinyint(1) not null default '0',
Now create an activate function elsewhere, once complete update activated === 1 for the user
When you do you login check, consider:
Upvotes: 1
Reputation: 6190
I think you are using 'char' data type in the database for the activation. So you better try this code.
if (trim($activation)!= "")
{
}
Cheers!
Prasad.
Upvotes: 0