0

我正在转换为 PDO,但在它检查用户名和电子邮件是否被占用的部分转换时遇到问题。

下面是代码:

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

我得到的错误在以下两行:

if(mysql_num_rows($usernamecheck) > 0){

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

提前致谢。

4

2 回答 2

1

您正在使用mysql_num_rows()PDO 查询。您不能混合使用这些 API。

您还将 $_POST 变量直接插入到您的 SQL 中,这是安全的禁忌。使用 PDO 的好处是您可以轻松地改用 SQL 查询参数,这样更容易也更安全。

以下是我编写此任务的方式:

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

还要记住,即使你先检查,你也应该假设有一天两个人可能试图同时创建相同的用户名,如果他们各自请求的代码以错误的顺序执行,他们都可能被告知用户名不存在,继续插入它。因此,您应该在必须唯一的列上定义一个 UNIQUE KEY。只有第一个 INSERT 会成功,另一个会出错。所以你必须检查错误。

于 2013-07-18T00:10:32.563 回答
1

首先,整个任务相当没有意义。使用户名独一无二是没有意义的。给定电子邮件用于识别用户,用户名 - 或者更确切地说 -显示名称可以是任何内容并允许重复,就像在 Stack Overflow 上所做的那样。

但是,如果您希望用户名是唯一的,显然它可以在一个查询中完成,而没有任何基本上无用的 num rows 功能

$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";
    }
}
于 2021-03-24T06:58:24.013 回答