1

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.

10
  • 4
    var_dump($check) gives what? You should not use addslashes nor md5. Parameterize your query and use password_hash (and password_verify where needed). Commented Jul 15, 2019 at 11:21
  • also to add to @user3783243 's comment this method/approach is also prone to race conditions.. If you want to prevent duplicates you should be adding a unique key to the table (also).. Commented Jul 15, 2019 at 11:22
  • @user3783243 it look something like this object(mysqli_result)#3 (5) { ["current_field"]=> int(0) ["field_count"]=> int(1) ["lengths"]=> NULL ["num_rows"]=> int(1) ["type"]=> int(0) } Commented Jul 15, 2019 at 11:27
  • 1
    "i think, username and email both fields using as unique values? right, then why are you using OR condition here?" @devpro some applications allow signin on a username OR email.. Commented Jul 15, 2019 at 11:49
  • 1
    Depends entirely on the application. Can separate users have the same username or the same email? Or is it just the combination that's unique? I would say the email is at least supposed to be unique, but again - depends on what the application does and what the structure is. Commented Jul 15, 2019 at 12:02

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

3 Comments

keep in mind that this is still prone to race conditions, assuming there is non unique key in the table..
Fair point - you can use use INSERT INTO ... ON DUPLICATE KEY UPDATE username=username or something along those lines, then check what the affected rows were, or possibly the inserted ID.
Indeed it would. Quite assumptious of me really, we haven't seen any tablestructure posted with the question.
0

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.

3 Comments

it gain error Notice: Undefined property: mysqli_result::$num_row
Please add some explanation to your answer such that others can learn from it
try updated code. I have checked on my database also.It will surely run.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.