1

Function

  public function isUsernameAvailable($username) {
        $sql = "SELECT COUNT(*) FROM users WHERE username = '$username'";
        $sql = $this->db->quote($sql);

        if ($sth = $this->db->query($sql)) {
            if ($sth->fetchColumn() > 0) {
                return false;
            } else {
                return true;
            }
        }
    }


if (!$user->isUsernameAvailable($_POST['username'])) {
        echo 'The username is already taken!';
        $error = 1;
    }

I get the output "The username is already taken!" even though It isn't.

John
  • 2,900
  • 8
  • 36
  • 65
  • 1
    Then do some debugging. The comparison on `fetchColumn()` probably doesn't work that way. Try outputting what it results in using `var_dump()` – Pekka Nov 19 '11 at 10:18
  • 5
    If you're using `PDO`, you're misusing prepared statements/escaping. – deceze Nov 19 '11 at 10:21

6 Answers6

3

select count(*)... will ALWAYS return a record, even nothing is matched

so, you can try this :

select 1 from ...;

between, a proper method to check any record return should be using rowCount

as indicate by the rest :-

  1. you should make use of bind rather than using quote
  2. function should always return a value
ajreal
  • 46,720
  • 11
  • 89
  • 119
1

Your isUsernameAvailable function will return NULL (equals to FALSE) when the query fails. This will trigger the The username is already taken! message.

Looks like your SQL query always fails, which I think is no wonder because you blindly apply quotes onto it.

After running a SQL query, you must more properly deal with the case that the query failed, e.g. display that an internal SQL error occured and log it, so you can look into the log and locate the cause of the error.

Additionally, you should use the PDO more properly, specifically when you want to prevent SQL injection (which you must care about). See Best way to stop SQL Injection in PHP.

Community
  • 1
  • 1
hakre
  • 193,403
  • 52
  • 435
  • 836
1

Use rowCount() instead of fetchColumn()

  if ($sth->rowCount() > 0) {
Adithya Surampudi
  • 4,354
  • 1
  • 17
  • 17
0

fetchColumn returns false if there is no column and also see ajreal answer.

    if ($sth = $this->db->query($sql)) {
        if ($sth->fetchColumn() == false) {
            return true;
        } else {
            return false;
        }
    }
Joost
  • 1,426
  • 2
  • 16
  • 39
0

Can you try using the following code?

$st->rowCount() > 0 
apaderno
  • 28,547
  • 16
  • 75
  • 90
Sudhir Bastakoti
  • 99,167
  • 15
  • 158
  • 162
0
$sql = "SELECT COUNT(*) FROM users WHERE username = '$username'";
$sql = $this->db->quote($sql);

You are quoting the whole query, this does not make any sense and is outright dangerous from a security standpoint – and probably results in an invalid query anyway.

Here's a more proper code:

// return TRUE if user is available
public function isUsernameAvailable($username) {
    $sql = "SELECT id FROM users WHERE username = :username";
    $stmt = $this->db->prepare($sql);
    $stmt->execute(array(':username' => $username));

    return $stmt->fetch() === FALSE;
}


if (!$user->isUsernameAvailable($_POST['username'])) {
    echo 'The username is already taken!';
    $error = 1;
}
knittl
  • 246,190
  • 53
  • 318
  • 364