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.
Related
I am trying to make a condition where the code checks if a phone number exists in DB and then the username.
$query1 = "SELECT `Phone` FROM `NewUser` WHERE Phone=?";
$query2 = "SELECT `Username` FROM `NewUser` WHERE Username=?";
// checks the Phone number existence
if($stmt = $LINK->prepare($query1)){
$stmt->bind_param("s", $Phone);
if($stmt->execute()){
$stmt->store_result();
$Phone_check= "";
$stmt->bind_result($Phone_check);
$stmt->fetch();
if ($stmt->num_rows == 1){
echo "That Phone already exists.";
die();
}
}
}
// checks the Username existence
elseif($stmt2 = $LINK->prepare($query2)){
$stmt2->bind_param("s", $User);
if($stmt2->execute()){
$stmt2->store_result();
$User_check= "";
$stmt2->bind_result($User_check);
$stmt2->fetch();
if ($stmt2->num_rows == 1){
echo "That Username already exists.";
die();
}
}
}
if the first condition is true I get That phone already exists but if the second condition occurs I get a white page.
When I swap the conditions then I get "That Username already exists."
As was pointed out in the comments if($stmt = $LINK->prepare($query1)) will return true regardless of whether the record exists or not. You need to remove all these if statements and simplify your code.
If you do not need to fetch the data into PHP to use it for something else, then there is absolutely no reason to fetch it. You can just check if the row exists with SQL. Since both columns belong to the same table you can do it in a single statement, too.
$stmt = $LINK->prepare("SELECT COUNT(*) FROM `NewUser` WHERE Phone=? OR Username=?");
$stmt->bind_param("ss", $Phone, $User);
$stmt->execute();
$stmt->bind_result($exists);
$stmt->fetch();
if ($exists) {
echo "The phone number or the username already exists.";
die();
}
This question already has answers here:
How to check if a row exists in MySQL? (i.e. check if username or email exists in MySQL)
(4 answers)
Closed 3 years ago.
I'm trying to check the database for a taken username when the user signs up. The connection to the database works fine as a similar password will be added to the table.
$username = $_POST['user'];
$password = $_POST['password'];
$hash = password_hash($password, PASSWORD_DEFAULT);
$s = 'SELECT * FROM users WHERE username = "$username"';
$result = mysqli_query($con, $s);
$num = mysqli_num_rows($result);
if ($num == 1) {
echo "Username is taken";
}else {
table for users
It goes to the else and adds the username to the database anyways. I have checked to make sure there isn't more than one username, although a greater than sign would work better anyway. any ideas?
Your code must be using parameter binding to send the value of $username to the database, otherwise "$username" is treated as a literal string. It will also protect your from SQL injections.
It would probably be better to create a UNIQUE key on that column instead. If you want to do it in the application layer for whatever reason, you can fetch the result and use that.
$stmt = $con->prepare('SELECT * FROM users WHERE username = ?');
$stmt->bind_param('s', $username);
$stmt->execute();
$result = $stmt->get_result()->fetch_all();
if ($result) {
echo "Username is taken";
} else {
// No such username in the database yet
}
This is not going to be very efficient, so we can simplify it using COUNT(1). It will return a single value containing the number of matching rows.
$stmt = $con->prepare('SELECT COUNT(1) FROM users WHERE username = ?');
$stmt->bind_param('s', $username);
$stmt->execute();
$usernameTaken = $stmt->get_result()->fetch_row()[0];
if ($usernameTaken) {
echo "Username is taken";
} else {
// No such username in the database yet
}
For more explanation see https://phpdelusions.net/mysqli/check_value
$s = 'SELECT * FROM users WHERE username = "$username"';
You are using double quote inside single quote so there is no interpolation happening. Change the order to
$s = "SELECT * FROM users WHERE username = '{$username}'";
I am trying to check if a posted username already exists in my database. I am not sure where I am going wrong. The other conditions below are working correctly. When I submit the form I always receive "Username taken" even when no such name exists in my db. Any help would be greatly appreciated. Thanks!
$username = $_POST['username'];
$stmt = $mysqli->prepare('SELECT COUNT(*) FROM users WHERE username = ?');
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();
if(isset($_POST["submit"]))
{
if(empty($_POST["username"]))
{
echo '<script>alert("Username field empty")</script>';
} else if(empty($_POST["password"])) {
echo '<script>alert("Password field empty")</script>';
} else if(!filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo '<script>alert("Incorrect email format")</script>';
} else if($stmt->num_rows > 0) {
echo '<script>alert("Username taken")</script>';
selec count(*) ... always returns 1 record, with the count. So, when you check else if($stmt->num_rows > 0), then it always returns true. You should check the value returned by count, not the number of records.
$conn properly connects to the database.
The users table of the database consists of the following fields id,name, email, username and password. One of the entries in the table contains benedict as the value for the username.
Code:
$userslist = $conn->prepare("SELECT * FROM users WHERE username=?");
$userslist->bind_param("s",$user);
$usersresult=$userslist->execute();
if($userslist->num_rows>0)
{
$userErr="Username already exists";
$errors++;
}
Problem:
When I enter a username(which is being stored in $user) with benedict as the value, the code does not detect duplicate id in spite of already having such a username. Further, $userslist->num_rows when printed shows 0.
On the contrary the following code correctly identifies, that a duplicate id already exists and prints the errror. (this proves there is no connection error or table errors)
$query="SELECT * FROM users WHERE username='".$user."'";
$qresult=mysqli_query($conn,$query);
if($qresult->num_rows>0)
{ $userErr="Username already exists";
$errors++;
}
I am aware that unique key and PDO is a better solution. But why it doesn't prints proper results while using prepared statements.
An affected rows result of: -1 indicates the query returned an error and therefore wasnt executed.
Check your query for errors in column/tables names etc.
Is your connection working?
Please try the following to debug:
$userslist = $conn->prepare("SELECT * FROM users WHERE username=?");
$userslist->bind_param("s",$user);
$usersresult=$userslist->execute();
print_r($conn->error);
Id suggest using PDO to start with, it is much safer for DB queries. http://php.net/manual/en/book.pdo.php . I would also suggest that you use a count for this and not a SELECT *. This is a wasteful check to see if a row exists, it will be more efficient by using a count.
You would do this using PDO like this.
$stmt = $db->prepare("SELECT count(1) FROM users WHERE username=?");
$stmt->execute(array($user));
$result = $stmt->fetch();
if($result)
{
if($result[0] == 1) echo "Username already taken";
else "username free";
}
else
{
echo "error";
}
You could do something like this.
if(mysqli_num_rows($userslist) > 0){
echo "username already exists"
}
check if row exists with mysql - similiar question
Have you tried:
$conn = new mysqli("localhost","user","password","db");
$sql = "SELECT * FROM users where username='".$_POST['username']."'";
$result = $conn->query($sql);
$count = $result->num_rows;
if($count > 0)
{
echo "Username ".$_POST['username']." already exists!";
}
So error is not affected row: check why the query failed:
`
<?php
$userslist = $conn->prepare("SELECT * FROM users WHERE username=?");
$userslist->bind_param("s",$user);
$usersresult=$userslist->execute();
if($userslist->num_rows>0)
{
$userErr="Username already exists";
$errors++;
}
elseif($userlist->affected_rows == -1) {
echo 'An error occurred: ' . $conn->error;
}
?>
`
but you do realise, in the few milliseconds between the check and an actual insert, there might be an other user inserting that exact same name?
Added: how to do it when username is unique indexed:
<?php
$userslist = $conn->prepare("INSERT INTO users (username, name, etc) VALUES (?,?, ?)");
$userslist->bind_param("sss",$user, $name, $etc);
$usersresult=$userslist->execute();
if($conn->errno == 1062) {
$userErr="Username already exists";
$errors++;
}
elseif($conn->errno) {
echo 'An error occurred: ' . $conn->error;
}
else {
if($userlist->affected_rows == 1) {
echo 'success';
}
else {
echo 'unknown why not inserted';
}
}
?>
Here is some background information on what I'm trying to do here. I'm try to create a registration form for my website (successful so far until this point). Data can be entered into the DB. The only thing I'm trying to do now is prevent duplicate email/usernames from being entered into the db. Through much stackoverflow research, I have found and tested the following code:
$query = "SELECT COUNT(*) AS num_rows FROM users WHERE email = ?";
$stmt = $mysqli->prepare($query);
$stmt->bind_param("s", $email);
if ($stmt->execute()) {
return $stmt->num_rows;
}
What I then do is following:
if(user_exists($user_email) > 0) {
echo "Email already exists!";
}
But is passes by this if statement as if the email does exist in the database!
The email I'm trying to enter, for my tests is testemail#testemailweb.com which is already in the database! Would someone possibly point out where I have messed up in my code? Is there a silly mistake that I could have possibly done when trying to perform this?
The fix for your particular problem here is by not using COUNT(*) as mentioned by John and not depend on mysqli_stmt->num_rows by using a buffered result set:
$query = "SELECT * FROM users WHERE email = ?";
$stmt = $mysqli->prepare($query);
$stmt->bind_param("s", $email);
return $stmt->execute() && $stmt->store_result() && $stmt->num_rows > 0;
Addendum
The only thing I'm trying to do now is prevent duplicate email/usernames from being entered into the db
You will want to use table constraints to prevent this (not just from the app, but anything else that can access the database). This has the added benefit of guarding against race conditions.
ALTER TABLE users ADD UNIQUE(email);
This will raise an error if you attempt to insert a row with an email value that already exists. You can check for this error on the application side and do whatever you want with it.
Your query will always return 1 row. COUNT(*) will return a result set even if only to report no rows match your query. As a result user_exists() always returns 1.
Change your query to:
$query = "SELECT * FROM users WHERE email = ?";
Now if no rows match your query $stmt->num_rows will be 0 so user_exists() will return 0.
change:
if ($stmt->execute()) {
return $stmt->num_rows;
}
What I then do is following:
if(user_exists($user_email) > 0) {
echo "Email already exists!";
}
to
$j=0;
if ($stmt->execute()) {
$j= $stmt->num_rows;
} else {
echo "Email already exists!";
}