Sam Bo
Sam Bo

Reputation: 23

PDO and checking if username or email is taken

I am converting to PDO and I'm having a problem converting at the section where it checks to see if the username and email is taken or not.

below is the code:

<?php
session_start();
$host     = "localhost";
$username = "root";
$password = "123";
$dbname   = "test";
$conn = new PDO("mysql:host=$host;dbname=$dbname",$username,$password);
?>

<?php
if(isset($_POST['register'])){
$username = $_POST['username'];
$password = $_POST['password'];
$email = $_POST['email'];

    $usernamecheck = $conn->query("SELECT `id` FROM `user` WHERE                   username='$username'");
    $emailcheck  = $conn->query("SELECT `id` FROM `user` WHERE email='$email'");
    if(mysql_num_rows($usernamecheck) > 0){
        echo "That username is already taken";
    }elseif(mysql_num_rows($emailcheck) > 0){
        echo "That e-mail address is already in use";
}    
?>

The errors I get are at the two following lines:

if(mysql_num_rows($usernamecheck) > 0){

}elseif(mysql_num_rows($emailcheck) > 0){

Thanks in Advance.

Upvotes: 0

Views: 2311

Answers (2)

Your Common Sense
Your Common Sense

Reputation: 157880

First of all, the entire task is rather pointless. Making a username unique makes no sense. Given email is used to identify a user, the username - or, rather - display name could be anything and allow duplicates, just like it is done right here, on Stack Overflow.

But if you want the username to be unique, obviously it can be done in one query, without any num rows functionality which being essentially useless

$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$sql = "SELECT username, email AS count FROM `user` WHERE username=? OR email=?";
$stmt = $conn->prepare($sql);
$stmt->execute([$username, $email]);
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    if ($row['username'] === $username) {
        $errors[] = "Username is taken";
    }
    if ($row['email'] === $email) {
        $errors[] = "Email is taken";
    }
}

Upvotes: 1

Bill Karwin
Bill Karwin

Reputation: 562651

You're using mysql_num_rows() for a PDO query. You can't mix these APIs.

You're also interpolating $_POST variables directly into your SQL, which is a no-no for security. The benefit of using PDO is that you can easily use SQL query parameters instead, which is much easier and more secure.

Here's how I'd code this task:

$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$stmt = $conn->prepare("SELECT COUNT(*) AS count FROM `user` WHERE username=?");
$stmt->execute(array($username));
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
  $username_count = $row["count"];
}
if ($username_count > 0) {
  echo "That username is already taken";
}

$stmt = $conn->prepare("SELECT COUNT(*) AS count FROM `user` WHERE email=?");
$stmt->execute(array($email));
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
  $email_count = $row["count"];
}
if ($email_count > 0) {
  echo "That email address is already in use";
}

Also keep in mind that even if you check first, you should assume that someday two people may be trying to create the same username simultaneously, and if the code for their respective requests executes in just the wrong sequence, they could both be told the username does not exist, go ahead and INSERT it. So you should define a UNIQUE KEY on the columns that must be unique. Only the first one to INSERT will succeed, the other will get an error. So you must check for errors.

Upvotes: 1

Related Questions