【问题标题】:PDO user verificationPDO 用户验证
【发布时间】:2012-12-23 15:06:49
【问题描述】:

count($existuser) 函数始终返回 1。即使没有具有该名称或电子邮件的用户。

代码如下:

function registerUser($username, $password, $passwordagain, $email, $mcname) {
    include $_SERVER['DOCUMENT_ROOT'] . "/config/config.php";
    $conn          = new PDO('mysql:host=' . $ip . ';dbname=' . $database, $username, $password);
    $validusername = "/^[a-z0-9]+$/";
    $validpassword = "/^[A-Za-z0-9]+$/";
    $validemail    = "/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/";
    $validmcname   = "/^[A-Za-z0-9]+$/";
    $error         = 0;

    if (strlen($username) < 4 || strlen($username) > 24) {
        $error = 1;
    }
    if (strlen($password) < 6 || strlen($password) > 24) {
        $error = 1;
    }
    if (strlen($mcname) < 4 || strlen($mcname) > 24) {
        $error = 1;
    }
    if (!preg_match($validusername, $username)) {
        $error = 1;
    }
    if (!preg_match($validpassword, $password)) {
        $error = 1;
    }
    if (!preg_match($validemail, $email)) {
        $error = 1;
    }
    if (!preg_match($validmcname, $mcname)) {
        $error = 1;
    }
    if ($password != $passwordagain) {
        $error = 1;
    }
//test
    $userquery = $conn->query('SELECT * FROM users WHERE username="' . $username . '"');
    $existuser = $userquery->fetch();
    echo count($existuser);
//test
    if (count($existuser)) {
        $error = 1;
        echo "<div class='erroralert'>Username already exists!</div>";
    }
//test
    $emailquery = $conn->query('SELECT * FROM users WHERE email="' . $email . '"');
    $existemail = $emailquery->fetch();
//test
    if (count($existemail)) {
        $error = 1;
        echo "<div class='erroralert'>E-mail already exists!</div>";
    }
    if ($error != 1) {
        $encryptedpassword = hash('sha512', $password);
        $registeruser      = $conn->query("INSERT INTO users(username, password, email, mcname) VALUES ('$username', '$encryptedpassword', '$email', '$mcname')");
        echo "<div class='successalert'>Succesfully registred</div>";
    }
}

【问题讨论】:

  • 我没有看到您发布的查询,而且您的调试过程也可以更改您的错误状态,这样您就可以确定您/用户在函数中输入的内容有什么问题.
  • 请参阅:php.net/faq.passwords.php - 您也可以将用于验证的长度约束放入正则表达式中(您已经使用电子邮件正则表达式执行此操作)并且您应该在此处使用准备好的语句,因为您不需要处理验证结果。

标签: php mysql pdo


【解决方案1】:

如果你这样做,你为什么要使用 PDO:

$userquery = $conn->query('SELECT * FROM users WHERE username="' . $username . '"');
$existuser = $userquery->fetch();

你应该有以下逻辑:

$userquery = $conn->prepare('SELECT * FROM users WHERE username = ?');
$userquery->execute(array($username));
if ($userquery->rowCount()) {
    // found user
} else {
    // user not found
}

【讨论】:

  • 注意SELECTPDOStatement::rowCount() 不能很好地结合在一起,请参阅stackoverflow.com/a/14012410/367456
  • @hakre 我同意在便携式应用程序上它是有效的,但如果你不做一个,你做两个查询而不是一个。
  • 哦,对于 Mysql,您可以这样做,对吧:Work-around for PHP5's PDO rowCount MySQL issue - 但是,这不是您在回答中建议的内容。
  • @hakre 我想我说得不够清楚。我并不是说他应该使用rowCount() 来获得受选择影响的确切行数。我是说如果它不返回 0,则有行。试试看。金额错误,但不是 0。如果没有行,则为 0。如果我错了,请纠正我。
  • 我只是说它在使用 Mysql 的每个系统上都不是这样工作的。就这样。我还更新了我的答案以突出问题的具体原因,并且修复相当简单(您在准备好的声明中有一个很好的观点)。
【解决方案2】:

查询可能无法执行,这就是为什么你总是得到“1”,这可能是错误报告。

通读你的代码,我建议你试试这个:

在以下查询中,您将用户名括在“”中,但是,这并不总是受支持,而是您应该使用单引号 ' 并将字符串本身用“括起来。所以下面一行

$userquery = $conn->query('SELECT * FROM users WHERE username="' . $username . '"');

应该是

$userquery = $conn->query("SELECT * FROM users WHERE username='" . $username . "'");

对有相同问题的其他查询执行相同操作。

【讨论】:

    【解决方案3】:

    您在这里使用了count() 错误。对于任何普通变量,它将返回 1,对于数组,它将返回元素的数量。

    重要的部分是第一个。如果没有行,PDOStatement::fetch() 将返回FALSE,它计数为 1,即为真:

    count(FALSE);      # 1
    count($existuser); # 1 when there is no user, when there is a user at least 2
                       #   for default fetchmode PDO::FETCH_BOTH
    

    所以你什么都没检查。而是测试它是 not FALSE:

    if ($existuser === FALSE) {
       // error.
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-10
      • 2015-12-31
      • 1970-01-01
      • 1970-01-01
      • 2015-04-21
      • 1970-01-01
      • 1970-01-01
      • 2019-07-24
      相关资源
      最近更新 更多