如何检查MySQL中是否存在行?(即检查MySQL中是否存在用户名或电子邮件)

How to check if a row exists in MySQL? (i.e. check if username or email exists in MySQL)

提问人:user2882684 提问时间:3/7/2014 最后编辑:Dharmanuser2882684 更新时间:5/8/2023 访问量:120928

问:

我需要帮助检查数据库中是否存在行。就我而言,该行包含一个电子邮件地址。我得到的结果:

email no longer exists [email protected]

这是我目前正在使用的代码:

if (count($_POST)) {
    $email = $dbl->real_escape_string(trim(strip_tags($_POST['email'])));

    $query = "SELECT `email` FROM `tblUser` WHERE `email` = '$email'";
    $result = mysqli_query($dbl, $query);
    if (is_resource($result) && mysqli_num_rows($result) == 1) {
        $row = mysqli_fetch_assoc($result);
        echo $email . " email exists " .  $row["email"] . "\n";
    } else {
        echo "email no longer exists" . $email . "\n";
    }
}

有没有更好的方法来检查MySQL数据库中是否存在行(就我而言,检查MySQL中是否存在电子邮件)?

php mysql mysqli pdo

评论

2赞 Digital Chris 3/7/2014
$query 是一个字符串,所以 is_resource($query) 总是会失败......您没有运行查询。
0赞 Funk Forty Niner 3/7/2014
阅读 is_resource()
0赞 T.Todua 8/16/2016
可能重复 测试MySQL表中是否存在行的最佳方法
1赞 Brad 7/15/2017
切勿将数据直接连接到查询中...它会产生模棱两可的查询,从而导致错误和安全问题。使用预准备/参数化查询来完全避免此问题。至少,必须使用适当的逃逸。

答:

8赞 Emilio Gort 3/7/2014 #1

您必须执行查询并在查询中向$email添加单引号,因为它是一个字符串,并删除$query是一个字符串,$result将是资源is_resource($query)

$query = "SELECT `email` FROM `tblUser` WHERE `email` = '$email'";
$result = mysqli_query($link,$query); //$link is the connection

if(mysqli_num_rows($result) > 0 ){....}

更新

根据您的编辑,只需更改:

if(is_resource($query) && mysqli_num_rows($query) > 0 ){
        $query = mysqli_fetch_assoc($query);
        echo $email . " email exists " .  $query["email"] . "\n";

if(is_resource($result) && mysqli_num_rows($result) == 1 ){
        $row = mysqli_fetch_assoc($result);
         echo $email . " email exists " .  $row["email"] . "\n";

你会没事的

更新 2

更好的方法应该是使用一个存储过程来执行以下 SQL,将电子邮件作为参数传递

SELECT IF( EXISTS (
                  SELECT *
                  FROM `Table`
                  WHERE `email` = @Email)
          , 1, 0) as `Exist`

并在 PHP 中检索值

假性尾腱:

 $query = Call MYSQL_SP($EMAIL);
 $result = mysqli_query($conn,$query);
 $row = mysqli_fetch_array($result)
 $exist = ($row['Exist']==1)? 'the email exist' : 'the email doesnt exist';

评论

1赞 Brian Powell 4/13/2016
我正在组建一个叫Pseudocodigo的乐队。
2赞 Brad 7/15/2017
切勿将数据直接连接到查询中...它会产生模棱两可的查询,从而导致错误和安全问题。使用预准备/参数化查询来完全避免此问题。至少,必须使用适当的逃逸。
0赞 Emilio Gort 7/15/2017
@BradA better way should be have a Store Procedure that execute the following SQL passing the Email as Parameter
1赞 Brad 7/15/2017
@EmilioGort 这取决于您如何执行该存储过程!
0赞 Emilio Gort 7/15/2017
@Brad只是一个问题:MYSQL是否准备处理像@Email='[email protected]'这样的参数);下拉表用户;' ??
82赞 Funk Forty Niner 3/7/2014 #2

使用 mysqli 预准备语句传统方法

$query = "SELECT 1 FROM `tblUser` WHERE email=?";
$stmt = $dbl->prepare($query);
$stmt->bind_param("s", $email);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc();
$emailExists = (bool)$row;

使用 mysqli 现代方法盯着 PHP 8.2:

$query = "SELECT 1 FROM `tblUser` WHERE email=?";
$result = $dbl->execute_query($query, [$email]);
$row = $result->fetch_assoc();
$emailExists = (bool)$row;

使用 PDO 预准备语句

$email = $_POST['email'];
$stmt = $conn->prepare('SELECT 1 FROM `tblUser` WHERE email = :email');
$stmt->execute(["email" => $_POST['email']]);
$row = $result->fetch();
$emailExists = (bool)$row;
  • 最好使用准备好的语句来帮助防止 SQL 注入。

注意:

在处理上述使用/概述的表单和 POST 数组时,请确保 POST 数组包含值,将 POST 方法用于表单并匹配输入的命名属性。

  • 仅供参考:如果没有显式指示,则表单默认为 GET 方法。

注意: - 匹配。 不匹配。<input type = "text" name = "var">$_POST['var']$_POST['Var']

  • POST 数组区分大小写。

咨询:

检查引用时出错:

请注意,MySQL API 不会混合使用,以防您可能正在访问此问答并且您正在用于连接(和查询)。mysql_

  • 从连接到查询,必须使用相同的方法。

有关此内容,请咨询以下内容:

如果您正在使用 API,但无法使用它,请查阅以下有关 Stack 的问答:mysql_

这些函数已弃用,并将在将来的 PHP 版本中删除。mysql_*

  • 是时候踏入 21 世纪了。

您还可以向 (a) 行添加 UNIQUE 约束。

引用:

如何将唯一键添加到现有表(具有非唯一行)

评论

4赞 slaw 10/20/2015
我认为前 2 个例子不是注射安全的,而后 2 个是,这是对的吗?谢谢
1赞 Brad 7/15/2017
此处将数据连接到查询中的方法已损坏,不应使用。始终使用某种类型的参数化查询,或至少使用转义。
0赞 Funk Forty Niner 7/15/2017
@Brad “始终使用某种类型的参数化查询,或至少使用转义” - 错误。这不是我的答案吗?你到底在找什么?
0赞 Brad 7/15/2017
标记离开...你的代码连接起来是坏的,这就是现实。你下面的代码显然没问题。如果您编辑您的帖子并删除损坏的代码,我很乐意撤消反对票。而且,感谢您提请注意其他破碎的答案......我今天晚些时候会谈到这些。
0赞 Funk Forty Niner 7/20/2017
@Brad“你的代码连接在顶部是坏的”——你必须在这里具体说明,因为我看不出哪里有什么“坏”的,你只是在拖钓我,如果有的话。我的答案或使用的任何语法都没有错,请不要侮辱我。编辑:如果你说的是有效的语法,你可能认为它应该写成,我不知道。email='".$email."'email='$email'
2赞 robhoomph 1/12/2016 #3

验证后和 INSERT 之前,使用 mysqli(procedural) 检查用户名是否已存在。这有效:

//check if username already exists
       include 'phpscript/connect.php'; //connect to your database

       $sql = "SELECT username FROM users WHERE username = '$username'";
       $result = $conn->query($sql);

       if($result->num_rows > 0) {
           $usernameErr =  "username already taken"; //takes'em back to form
       } else { // go on to INSERT new record

评论

2赞 Brad 7/15/2017
切勿将数据直接连接到查询中...它会产生模棱两可的查询,从而导致错误和安全问题。使用预准备/参数化查询来完全避免此问题。至少,必须使用适当的逃逸。
6赞 Dharman 11/20/2019 #4

有多种方法可以检查数据库中是否存在值。让我演示如何使用 PDO 和 mysqli 正确完成此操作。

PDO

PDO是更简单的选择。要确定数据库中是否存在值,可以使用 prepared 语句和 fetchColumn()。无需获取任何数据,因此我们只会在值存在时获取。1

<?php

// Connection code. 
$options = [
    \PDO::ATTR_ERRMODE            => \PDO::ERRMODE_EXCEPTION,
    \PDO::ATTR_EMULATE_PREPARES   => false,
];
$pdo = new \PDO('mysql:host=localhost;port=3306;dbname=test;charset=utf8mb4', 'testuser', 'password', $options);

// Prepared statement
$stmt = $pdo->prepare('SELECT 1 FROM tblUser WHERE email=?');
$stmt->execute([$_POST['email']]);
$exists = $stmt->fetchColumn(); // either 1 or null

if ($exists) {
    echo 'Email exists in the database.';
} else {
    // email doesn't exist yet
}

有关更多示例,请参阅:如何检查数据库中是否存在电子邮件?

MySQLi的

与往常一样,mysqli 有点麻烦和限制,但我们可以使用类似的方法处理准备好的语句。

<?php

// Connection code
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new \mysqli('localhost', 'testuser', 'password', 'test');
$mysqli->set_charset('utf8mb4');

// Prepared statement
$stmt = $mysqli->prepare('SELECT 1 FROM tblUser WHERE email=?');
$stmt->bind_param('s', $_POST['email']);
$stmt->execute();
$exists = (bool) $stmt->get_result()->fetch_row(); // Get the first row from result and cast to boolean

if ($exists) {
    echo 'Email exists in the database.';
} else {
    // email doesn't exist yet
}

除了将结果行(甚至可能不存在)转换为布尔值之外,您还可以使用以下命令从第一行中获取和读取第一项COUNT(1)fetch_row()[0]

有关更多示例,请参阅:如何使用 mysqli 预处理语句检查数据库中是否存在值

次要备注

  • 如果有人建议你使用,不要听他们的。这是一种非常糟糕的方法,如果误用可能会导致性能问题。mysqli_num_rows()
  • 不要使用 .这并不意味着要用作对 SQL 注入的保护。如果正确使用准备好的语句,则无需担心任何转义。real_escape_string()
  • 如果要在尝试插入新行之前检查数据库中是否存在某行,则最好不要使用此方法。最好在数据库中创建一个唯一的键,如果存在重复值,则让它引发异常。