【问题标题】:Check if user exists in database检查用户是否存在于数据库中
【发布时间】:2013-08-31 07:49:59
【问题描述】:

我创建了一个用户类,它验证通过表单传递的数据,然后更新数据库表用户。我想添加额外的功能,例如检查用户名和电子邮件是否存在于表中,我添加了一个小脚本,但它似乎不起作用。

我插入了一个重复的电子邮件地址,但没有收到错误消息“电子邮件存在”,而是收到了成功消息“插入了 1 行”:

我在下面做错了吗?有没有更好的方法来解决这个问题?

 public function insert() {

if (isset($_POST['submit'])) {
    $email = isset($_POST['email']) ? $this->mysqli->real_escape_string($_POST['email']) : '';

$result = $this->mysqli->prepare("SELECT * FROM users WHERE email='".$email."'");

if ($result->num_rows) {
echo "email exisits!";
} 
 else
 {
$stmt = $this->mysqli->prepare("INSERT INTO users (username, password, name, email) VALUES (?, ?, ?, ?)");
        $stmt->bind_param('ssss', $username, $password, $name, $email); // bind strings to the paramater
        //escape the POST data for added protection

$username = isset($_POST['username']) ? $this->mysqli->real_escape_string($_POST['username']) : '';
$cryptedPassword = crypt($_POST['password']);
$password = $this->mysqli->real_escape_string($cryptedPassword);
    $name = isset($_POST['name']) ? $this->mysqli->real_escape_string($_POST['name']) : '';
    $email = isset($_POST['email']) ? $this->mysqli->real_escape_string($_POST['email']) : '';
        /* execute prepared statement */
$stmt->execute();
    printf("%d Row inserted.\n", $stmt->affected_rows);
    /* close statement and connection */
$stmt->close();
            }

【问题讨论】:

  • 也许如果您在email 上添加UNIQUE 索引,您可以有效地防止多个用户使用同一电子邮件。
  • 使用 /* 执行查询 / $result->execute(); / 存储结果 */ $result->store_result();然后使用 $result->num_rows()
  • 请注意,您的代码臃肿且错误。
  • @YourCommonSense 好的,感谢您富有洞察力的评论
  • @vishalshah 不,我没有,我现在就试试这个,谢谢

标签: php mysqli


【解决方案1】:

你正在使用你所能选择的最糟糕的 API。

使用 safeMysql 会是

$exists = $this->db->getOne("SELECT 1 FROM users WHERE email=?s", $_POST['email']);
if ($exists) {
    echo "email exisits!";
} 

使用 PDO 会稍微长一些,但可以使用

$stmt = $this->db->prepare("SELECT 1 FROM users WHERE email=?");
$stmt->execute(array($_POST['email']));
$exists = $stmt->fetchColumn();
if ($exists)
{
    echo "email exisits!";
} 

但是使用原始 mysqli,您将需要一屏代码来检查用户是否存在。

所以,使用 safeMysql 的整个函数将是

public function insert()
{
    if (!isset($_POST['submit'])) {
        return FALSE;
    }

    $sql    = "SELECT 1 FROM users WHERE email=?s";
    $exists = $this->db->getOne($sql, $_POST['email']);
    if ($exists)
    {
        echo "email exisits!";
        return FALSE;

    }
    $sql     = "INSERT INTO users SET ?u";
    $allowed = array('username', 'name', 'email');
    $insert  = $this->db->filterArray($_POST, $allowed);
    $insert['password'] = crypt($_POST['password']);
    $this->db->query($sql, $insert);
    return $this->db->afectedRows();
}

【讨论】:

  • 感谢会调查 PDO,我还认为准备好的陈述是好的做法吗? @YourCommonSense
  • 还是只是使用了MySQLi? @YourCommonSense
  • 准备好的陈述是很好的做法,但你使用它们的方式错误。
  • 好的,我明白了,你能给我一个正确的方式和我的方式的例子,所以我知道这一点,请@YourCommonSense
  • 我在回答中已经举了几个例子。 Burhan Khalid 的一个包含另一个
【解决方案2】:

你需要在prepare语句之后使用这段代码

$stmt->execute();
$stmt->store_result();

放这个

if ($result->num_rows > 0) {
echo "email exisits!";
} 

而不是

if ($result->num_rows) {
echo "email exisits!";
} 

【讨论】:

  • 确实有效,我需要像下面那样绑定我的结果吗?
  • 你需要使用 store_result() 来使用 num_rows
  • 你需要使用 $stmt->execute();在插入查询准备语句后
  • 我有点喜欢这个完全错误的答案在作者从其他 cmets 学习正确答案后最终被编辑的方式。
  • @YourCommonSense 你是什么意思?
【解决方案3】:

首先,您使用的是prepare(太棒了!),但随后您只是传递了电子邮件的价值,实际上破坏了准备好的语句的好处。

其次,您从不执行查询,这就是为什么您在 num_rows 中没有得到任何内容的原因。

public function insert() {

$result = $this->mysqli->prepare("SELECT COUNT(*) FROM users WHERE email=?");
$result->bind_param("s", $_POST['email']);
$result->execute();
$result->bind_result($email_count);

if ($email_count) {
    echo "email exisits!";
} else {
   # your other logic

【讨论】:

  • 我实现了这个但我得到了以下错误:Warning: mysqli_stmt::bind_param(): Number of variables doesn't match number of parameters in prepared statement in E:\xampp\htdocs\imanage\insert.php on line 52Fatal error: Call to a member function bind_param() on a non-object in E:\xampp\htdocs\imanage\insert.php on line 60我只定义了一个变量,它是电子邮件,所以不理解错误消息,有什么建议吗? @BurhanKhalid
  • 不,他的想法是正确的
【解决方案4】:

据我所知,在使用 if ($result->num_rows) 测试之前,您没有为 num_rows 分配值,因此它始终为 0

【讨论】:

    猜你喜欢
    • 2021-12-15
    • 2021-12-19
    • 1970-01-01
    • 1970-01-01
    • 2014-07-17
    • 2013-12-16
    • 2016-03-01
    • 1970-01-01
    相关资源
    最近更新 更多