Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/242.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何检查重复的用户名和/或电子邮件?_Php_Mysql_Sql_Pdo - Fatal编程技术网

Php 如何检查重复的用户名和/或电子邮件?

Php 如何检查重复的用户名和/或电子邮件?,php,mysql,sql,pdo,Php,Mysql,Sql,Pdo,我一直在想,如果在注册期间用户名和/或电子邮件重复,如何签入MySQL表。以下是我到目前为止尝试过但无效的内容: $username = $_POST['username']; $sq = $db->exec("SELECT * FROM `users` WHERE `username` = '$username'"); if ($sq->rowCount() > 0) { $msg = "That username is already taken."; $e

我一直在想,如果在注册期间用户名和/或电子邮件重复,如何签入MySQL表。以下是我到目前为止尝试过但无效的内容:

$username = $_POST['username'];
$sq = $db->exec("SELECT * FROM `users` WHERE `username` = '$username'");
if ($sq->rowCount() > 0)
{
    $msg = "That username is already taken.";
    $error = true;
}

$email = $_POST['email'];
$sq = $db->exec("SELECT * FROM `users` WHERE `email` = '$email'");
if ($sq->rowCount > 0)
{
    $msg = "That email is already taken.";
    $error = true;
}

if (!error)
{
    //add to db
}
这会导致对非对象的成员函数rowCount()调用


您能帮忙吗?

请澄清$db的类型,假设它是sqllite3

查看位于..的SQLLITE3::exec()文档。。据它所说,它只对(更新、插入、删除)有效,并返回布尔值。因此,您的代码可能不会运行

如果根据您的标签,您正在使用MySQL。我相信您需要查看mysql/mysqli扩展、mysql_query()&mysqli_query(),或者$db->query(),如果$db属于mysqli类型。

PDO::exec()
返回一个整数,那么您的上述代码将在调用非对象上的成员函数rowCount()时发生致命错误。为此,您应该做的是
选择COUNT(*)
以获取行数

您还可以使用异常来帮助错误处理过程

像这样:

// Ensure PDO will throw exceptions on error
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

// Turn emulated prepares off
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);

try {

  // Check if username is taken
  $stmt = $db->prepare("SELECT COUNT(*) FROM `users` WHERE `username` = :username");
  $stmt->execute(array('username' => $_POST['username']));
  if ($stmt->fetchColumn() > 0) {
    throw new Exception("That username is already taken.");
  }

  // Check if email is taken
  $stmt = $db->prepare("SELECT COUNT(*) FROM `users` WHERE `email` = :email");
  $stmt->execute(array('email' => $_POST['email']));
  if ($stmt->fetchColumn() > 0) {
    throw new Exception("That email is already taken.");
  }

  // Username and email are free

} catch (PDOException $e) {

  // A database error occured

} catch (Exception $e) {

  // Either the username of email is taken

}

如果列中的数据应该是唯一的,那么它应该有一个唯一的索引,以防止重复插入,并加快基于该列的值进行搜索的查询。

要避免潜在的争用情况,只需将用户名和电子邮件字段设置为唯一索引即可

当您尝试插入一个重复的行时,数据库引擎会给您一个特定的错误代码,对于MySQL,它是1062

如果查询失败,请检查错误号是否为重复行的错误号,并根据该错误号显示消息


至少,您的列应该是唯一的索引,以防止在数据库级别重复。

有什么问题?它根本不起作用吗?做一些意想不到的事?没有收到现有的用户名和电子邮件?哦,我知道我忘了什么。已编辑。您的代码易受SQL注入攻击。您真的应该使用,将变量作为参数传递到其中,而这些参数不会对SQL进行计算。如果您不知道我在说什么,或者如何修复它,请阅读的故事。我对PHP了解不多,但在第一个例子中,如果您在$sq->rowCount()中有paren,在第二个例子中,如果您只有$sq->rowCount()。这可能是一个问题吗?明确说明它是MySQL。或者甚至
SELECT存在(SELECT*FROM…
这样MySQL一旦找到一条匹配的记录就知道停止搜索,而不是继续寻找其他人,以便找到一个不感兴趣的总体计数。@eggyal出于这个原因,我想知道一个
限制1
。虽然为了公平起见,如果列应该是唯一的,它应该有一个唯一的索引,这样就不会真正优化它。我不认为
限制1
会有任何区别,因为它只适用于聚合结果(其中只有一条记录)。但是是的,
UNIQUE
键会使我的观点变得多余。@eggyal啊,是的,
LIMIT
是在收集结果之后应用的,所以我认为它不会影响性能。更新了答案,提到了唯一索引,并对其进行了重构,使其更好一些。如果我使列值唯一,它甚至会在执行此代码之前抛出一个mysql错误,不是吗?