pdo - 用户名已经存在,但事实并非如此

时间:2011-11-19 10:15:38

标签: php pdo

功能

  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;
    }

我收到输出“用户名已被占用!”即使不是。

6 个答案:

答案 0 :(得分:3)

select count(*)...始终返回记录,即使没有匹配

所以,你可以试试这个:

select 1 from ...;

之间,检查任何记录返回的正确方法应该是使用rowCount

由其他人指出: -

  1. 你应该使用bind而不是使用quote
  2. 函数应始终返回值

答案 1 :(得分:1)

当查询失败时,您的isUsernameAvailable函数将返回NULL(等于FALSE)。这将触发The username is already taken!消息。

看起来你的SQL查询总是失败,我认为这也就不足为奇了,因为你盲目地将引号应用到它上面。

运行SQL查询后,您必须更好地处理查询失败的情况,例如:显示发生内部SQL错误并记录它,以便您可以查看日志并找出错误原因。

此外,您应该更正确地使用PDO,特别是当您想要阻止SQL注入时(您必须关注它)。请参阅Best way to stop SQL Injection in PHP

答案 2 :(得分:1)

使用rowCount()而不是fetchColumn()

  if ($sth->rowCount() > 0) {

答案 3 :(得分:0)

如果没有列,fetchColumn返回false,并且还会看到ajreal answer。

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

答案 4 :(得分:0)

您可以尝试使用以下代码吗?

$st->rowCount() > 0 

答案 5 :(得分:0)

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

您正在引用整个查询,这没有任何意义,从安全角度来看是彻头彻尾的危险 - 并且可能导致无效的查询。

这是一个更恰当的代码:

// 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;
}