So I have a login system and I want to retrieve the first name of the person who is logged in. Here's my php:
function verify_Username_and_Pass($un, $pwd) {
$query = "SELECT `First Name`, Username, Password
FROM table
WHERE Username = :un AND Password = :pwd
LIMIT 1";
$stmt = $this->conn->prepare($query);
$stmt->bindParam(':un', $un);
$stmt->bindParam(':pwd', $pwd);
$stmt->execute();
if ($stmt->rowCount() > 0) {
// User exist
return true;
$stmt->close();
}
else {
// User doesn't exist
return false;
$stmt->close();
}
}
this is part of a class who has 1 private variable $conn. The login works perfectly but i just want to get the person's first name. How do I do that?
First off, NEVER grab the password from the database, that is just extremely bad practice.
Second, you only want to accept the user as correct if ONLY one row is returned.
lastly bindColumn is what you're looking for.
<?php
function verify_Username_and_Pass($un, $pwd) {
$query = "SELECT `First Name`, Username
FROM table
WHERE Username = :un AND Password = :pwd";
// Don't limit the query to only one, if there is a chance that you can
// return multiple rows, either your code is incorrect, bad data in the database, etc...
$stmt = $this->conn->prepare($query);
$stmt->bindParam(':un', $un);
$stmt->bindParam(':pwd', $pwd);
$stmt->execute();
// Only assume proper information if you ONLY return 1 row.
// Something is wrong if you return more than one row...
if ($stmt->rowCount() == 1) {
// User exist
$stmt->bindColumn('First Name', $firstName);
$stmt->bindColumn('Username', $username);
// You can now refer to the firstName and username variables.
return true;
$stmt->close();
} else {
// User doesn't exist
return false;
$stmt->close();
}
}
?>
That should work for you.
just change the query statement?
$query = "SELECT `First Name`
FROM table
WHERE Username = :un AND Password = :pwd
LIMIT 1";
if that throws errors, you would have to show more of what the class is doing to manage the db transaction
just change this line, to select only First Name in the query:
$query = "SELECT `First Name`, Username, Password
FROM table
WHERE Username = :un AND Password = :pwd
LIMIT 1";`
to
$query = "SELECT `First Name`
FROM table
WHERE Username = :un AND Password = :pwd
LIMIT 1";`
You need to bind the result as below
if ($stmt->rowCount() > 0) {
$stmt->bind_result($fname, $uname, $pwd);
$stmt->fetch()
echo $fname // here you get firsname
// either you can return this $fname or store into session variable for further
// User exist
return true;
$stmt->close();
}
else {
// User doesn't exist
return false;
$stmt->close();
}
In the section where you are returning true you could instead return the actual user data (and array with data will evaluate to true anyway).
Word of warning, you should use hashed passwords. Do not store the password y plain.
Related
I'm learning to create conditional event where sql checkout data where is exists before inserting data so they don't conflicted.
i've tried using mysql row check in php then check if query empty before i tried to validate the query executed properly.
also trying to close db connection when conditional satisfied but it worthless anyway.
$user = addslashes(strtolower($usr));
$mail = addslashes(strtolower($mail));
$pass = md5(addslashes($pwd));
$check = $db->query("SELECT EXISTS(SELECT *
FROM `users`
WHERE LOWER(`username`) = LOWER('$user')
OR LOWER(`email`) = LOWER('$mail'))");
if (!$check) {
$db->close();
return false;
} else {
$sql = "INSERT IGNORE INTO `users` (`username`, `password`, `email`)
VALUES ('$user', '$pass', '$mail')";
$query = $db->query($sql);
$db->close();
return true;
}
I'm expecting it execute my queries while data was empty and return false while data has been existed.
Your main issue is that $check will always be a truthy value, so long as the query never fails. If the query returns 0 rows, it is still a true object.
You should instead check if there were any values returned. You can also simplify the query quite a bit, given that MySQL is case-insensitive, and you don't need to check if the result exists. Using a prepared statement, the code would look like this
$stmt = $db->prepare("SELECT username FROM users WHERE username = ? OR email = ?");
$stmt->bind_param("ss", $usr, $mail);
$stmt->execute();
$check = $stmt->fetch();
$stmt->close();
// True if the user exists
if ($check) {
return false;
} else {
$stmt = $db->prepare(" INSERT INTO users (username, password, email) VALUES (?, ?, LOWER(?))");
$stmt->bind_param("sss", $usr, $pass, $mail);
$stmt->execute();
$stmt->close();
}
That said, you should not use md5() for passwords - use password_hash() with password_verify() instead.
you can change your code like this
$check = $db->query("SELECT EXISTS(SELECT * FROM `users`
WHERE LOWER(`username`) = LOWER('$user')
OR LOWER(`email`) = LOWER('$mail'))");
$check = $conn->query($sql);
$value = $check->fetch_row()[0];
if($value > 0 ){
echo "existed".$value; // you can change accordingly
}else{
echo "doesn't exist"; // this also
}
Because database respond the query in 1 for exist and 0 for non-exist so the num_row will be always 1 thats why we cant determine the existence with num_row so we have to fetch the value.
Given the following code:
$checkuname = $connect->prepare('SELECT * FROM user WHERE username = ?');
$checkuname->bind_param("s", $uname);
$checkemail = $connect->prepare('SELECT * FROM user WHERE email = ?');
$checkemail->bind_param("s", $email);
$match = 0;
if ($checkuname->execute()) {
//if username matches//
$erroruname = "This username exists, please enter a new one";
$match = $match + 1;
}
if ($checkemail->execute()) {
//if email matches//
$erroremail = "This email has been used, please enter another one";
$match = $match + 1;
}
if ($match == 0) { //if no match, good to push data into database// }
No matter what happens, it always returns me saying that username exists (when it doesn't).
Is there any way to correct this?
Or if you think there would be an easier or clearer way to check if both username and email exists in a database, please do share too.
Just to mention too: Most tutorials I have found uses a single variable to check, but I need to check 2 variables
"#Fred-ii- I'll invite you to post an answer and I'll mark it as solved – Timothy Wong Glash"
As requested by the OP:
You can do this in one query.
$query = "SELECT `email`, `username` FROM `user` WHERE email=? AND username=?";
if ($stmt = $connect->prepare($query)){
$stmt->bind_param("ss", $email, $uname);
if($stmt->execute()){
$stmt->store_result();
$email_check= "";
// Number of binded results must match the number of columns in SELECT
$stmt->bind_result($email_check, $username_check);
$stmt->fetch();
// or num_rows >0
if ($stmt->num_rows == 1){
echo "That records already exists.";
exit;
}
}else{ echo "Error: " . mysqli_error($connect); }
}
Well, you are checking if the query executes, but you are not checking if the values returned are correct or not. What you need to do is verify how many rows are returned after executing the query, if a row is returned the user has been found. You can do that with num_rows.
I'm using PDO for a connection into my db. There, I have a table where I store the users. In that table I have 5 columns: id, username, password, mail and sex.
What I really want is to store in a SESSION variable, the sex of the user that has been logged in. I don't know exactly what to use, because all the examples that I've seen, are usually for printing all the results of the db into the webpage with a foreach statement, but that isn't what I want.
Actually, this is the code that I have:
$connection = new PDO('mysql:host=localhost;dbname=db', "user", "password");
$sql = 'SELECT * FROM users WHERE username = :username AND password = :password';
$statement = $connection->prepare($sql);
$statement->bindParam(':username', $_POST['username'], PDO::PARAM_STR, 12);
$statement->bindParam(':password', $_POST['password'], PDO::PARAM_STR, 30);
$result = $statement->execute();
if ($result) {
$result = $statement->fetchAll();
if (!empty($result)){
$_SESSION['login'] = true;
$_SESSION['username'] = $_POST['username'];
echo 'Hello '.$_POST['username'].', you have been connected successfully.';
}
else {
echo 'Sorry, this user do not exist.';
}
}
So, this is correctly working.
But now, what I want is to store the sex value from the db in a $_SESSION['sex'] variable. How can I do that?
Thanks.
You can just add in the session after username, you have already slected from your query
$_SESSION['username'] = $_POST['username'];
$_SESSION['sex'] = $result[0]['sex'];
You might want to remove $result from query execution, so this line
$result = $statement->execute();
Will be
$statement->execute();
Just assign it from the result row:
$_SESSION['sex'] = $result[0]['sex'];
You have to use [0] because you used fetchAll, which returns a 2-dimensional array of rows and columns.
Do I have to put results from a query into an array if I know I'm only going to receive one password from the database? I'm using:
$sql = 'SELECT password FROM users WHERE userName="'.$username.'" LIMIT 1';
$result = $con->query($sql);
$row = $result->fetch_array(MYSQLI_NUM);
$hash = crypt($password,$row[0]);
if($row[0] == $hash){}
if you have stored hash in database (which you should) then you don't have to hash it again. also use prepared statement on user input.
$sql = $con->prepare("SELECT password FROM users WHERE userName=? LIMIT 1 ");
$sql->bind_param("s", $username);
$sql->execute();
$sql->bind_result($password_db);
while ($sql->fetch()) {
$hash = crypt($password,$password_db);
if($password_db == $hash){}
}
http://www.php.net/manual/en/mysqli-stmt.prepare.php
You could use list instead:
list($passwd) = $result->fetch_array(MYSQLI_NUM);
if($passwd == $hash) {
};
Here's the PHP reference
Since $result->fetch_array(MYSQLI_NUM) is returning an array type, you could reference it directly:
if($result->fetch_array(MYSQLI_NUM)[0] == $hash)
...
I am having trouble checking if a row exists to log someone in.
The password is salted in the db using the password+ the email
I am using PDO.
function is_valid_developer($username, $password)
{
global $db;
$query = 'SELECT COUNT(*) FROM users WHERE username = :username AND password = sha(CONCAT(:password,(SELECT email FROM users WHERE username = :password))) AND developer = true';
$statement = $db->prepare($query);
$statement->bindValue(':username', $username);
$statement->bindValue(':password', $password);
$statement->execute();
$count = $statement->fetchColumn();
if ($count === 1)
{
return TRUE;
}
else
{
return FALSE;
}
}
Your subquery appears to be incorrect (see the WHERE username = :password clause), and will likely never return any results. Further, using the same bound parameter twice is not supported in PDO (you use :password twice). Besides that, you don't actually need a subquery at all; try this query:
SELECT COUNT(*) FROM users
WHERE username = :username
AND password = sha(CONCAT(:password, email))
AND developer;
Further, make sure you call $statement->closeCursor() after your call to $statement->fetchColumn(); leaving PDO statement cursors open after you are done with them may cause the database to fail on all future queries.