【问题标题】:PDO Username validation if already existsPDO 用户名验证(如果已存在)
【发布时间】:2017-10-19 05:11:30
【问题描述】:

我的注册表有问题。我的表单可以正常工作,但是每当我尝试插入已经存在的用户名时,它都不会显示任何错误。

这是我的 php 注册文件:

<?php
$servername = "localhost";
$username = "root";
$password = "";

try {
    $conn = new PDO("mysql:host=$servername;dbname=dblogin", $username, $password);

    // set the PDO error mode to exception
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    if (isset($_POST['submit'])) {
        $user_name = $_POST['user_name'];
        $user_email = $_POST['user_email'];
        $user_pass = $_POST['user_pass'];
        $hash = password_hash($user_pass, PASSWORD_DEFAULT);

        $stmt = $con->prepare("SELECT user_name FROM users WHERE user_name = :user_name");

        if($stmt->rowCount() > 0){
        echo "exists!";
        }

       else{  
        $insert = $conn->prepare("INSERT INTO users (user_name,user_email,user_pass) values(:user_name,:user_email,:user_pass)");

        $insert->bindparam(':user_name',$user_name);
        $insert->bindparam(':user_email',$user_email);
        $insert->bindparam(':user_pass',$hash);


        $insert->execute();    
      }
    }
 catch(PDOException $e)
    {
    echo "connection failed";
    }


?> 

感谢您的支持

【问题讨论】:

  • 你在 if 语句中错过了 1 } if (isset($_POST['submit'])) { if($stmt->rowCount() > 0){ echo "exists!"; } }
  • 您的代码格式有点偏离,因此很难看到,但看起来try 块缺少},因此会导致解析错误。 ini_set('display_errors',1);error_reporting(E_ALL); 会告诉你这个
  • 另外你的第一个 stmt 有错字:$con 而不是 $conn。
  • 一个建议:不要使用rowCount(),因为它不太可靠 - 请参阅PDOStatement::rowCount 的“描述”部分。使用PDOStatement::fetch 并检查结果是否为 FALSE。如果为 FALSE,则未找到任何记录。否则它包含获取的记录。或者,作为fetch() 的替代方案,使用query(),如PDOStatement::rowCount 中的“示例#2”。
  • 另一个建议:不要使用setAttribute(),而是将驱动程序选项数组作为最后一个参数传递给$conn = new PDO(...);。为什么?阅读Connections and Connection management中“示例#4”之后的“注释”。

标签: php pdo registration


【解决方案1】:

您没有执行 select 语句。你需要绑定params并执行select语句,在select语句之后试试这个。

$stmt->bindparam(':user_name',$user_name);
$stmt->execute();

【讨论】:

    【解决方案2】:
     public function usernameCheck($username)
    {
    
        $sql = "SELECT * FROM $this->table where username = :username";
        $query = $this->pdo->prepare($sql);
        $query->bindValue(':username', $username);
        $query->execute();
        if ($query->rowCount() > 0) {
            return true;
    
        } else {
            return false;
        }
    
    }
    

    在你的项目中使用这个希望它会起作用...... :)

    【讨论】:

    • 感谢您的回复 atul 但在哪里插入此代码。你能给出完整的代码吗?我必须在else中放置insert声明
    • 嘿,你不需要做“if and else”事情,只需简单地在你的代码中调用我的函数它就可以工作(只需要为准备语句提供你的表名,只需提供你的连接(即$conn->prepare()))...自己做...如果您有任何问题请告诉我...
    【解决方案3】:

    if 语句中缺少 }

    if (isset($_POST['submit'])) {
            $user_name = $_POST['user_name'];
            $user_email = $_POST['user_email'];
            $user_pass = $_POST['user_pass'];
            $hash = password_hash($user_pass, PASSWORD_DEFAULT);
    
            $stmt = $con->prepare("SELECT user_name FROM users WHERE user_name = :user_name");
    
            if($stmt->rowCount() > 0){
            echo "exists!";
            }
    }else{
    
    }
    

    【讨论】:

    • 并且该语句从未像@farsheel Rahman 指出的那样执行
    • @andrew “但是每当我尝试插入已经存在的用户名时,它都不会显示任何错误。”试着理解这一点。顺便说一句,这并不难。
    • 我只是想通过指出代码中存在另一个错误来提供帮助,以便您可以改进您的答案,实际上还有另外两个错误,因为使用 $con 而不是 @987654323 @。为什么不读cmets?顺便说一句,这并不难
    【解决方案4】:

    我注意到 4 件事(其中 2 件事已被其他人提及):

    首先也是最小的是你有一个拼写错误($con 而不是 $conn)——别担心它会发生在我们最好的人身上——在你的第一个 $stmt 查询中,这意味着你的选择结果变为 NULL 而不是 0 - 所以你 rowCount 发现它没有超过 0 并且没有你的错误信息继续前进

    其次,您忘记在第一个 $stmt 查询中绑定和执行参数,这会为您的 rowCount 结果提供相同的结果

    第三,即使使用准备好的语句,也要始终清理变量 - 最少使用

    $conn->mysql_real_escape_string($variable);
    

    你可以利用优势

    htmlspecialchars($variable);
    

    第四,由于你没有对数据库做任何事情(除了查看),你可以通过简单的编写来简化你的代码:

    $stmt = $conn->query("SELECT user_name FROM users WHERE user_name = '$user_name' LIMIT 1")->fetch();
    

    正如我所说 - 无需在第一个查询中绑定或执行

    并且作为一般规则 - 永远不要使用 rowCount - 如果您必须知道结果的数量(并且在 99% 的情况下您不需要)使用 count();但是,如果您在这里只是想知道是否找到了任何东西,请使用:

    if ( $stmt ) {
        echo "exists!";
    } else {
        // insert new user as you did
    }
    

    编辑:

    另外 - 作为旁注 - 在您最初创建连接时应该考虑一些事项...

    例如:

    // Set variables
    $servername = "localhost";
    $username = "***";
    $password = "***";
    $database = "***";
    $charset = 'utf8'; // It is always a good idea to also set the character-set
    
    // Always create the connection before you create the new PDO
    $dsn = "mysql:host=$servername;dbname=$database;charset=$charset"; 
    
    // Set default handlings as you create the new PDO instead of after
    $opt = [
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // And add default fetch_mode
        PDO::ATTR_EMULATE_PREPARES   => false, // And ALWAYS set emulate_prepares to false
    ];
    
    // And now you are ready to create your new PDO
    $conn = new PDO($dsn, $username, $password, $opt);
    

    只是一个建议......快乐的小径

    【讨论】:

    • 对不起,我不想突兀 ;-) 我只想说,query() 语句在没有通过用户传递的任何 where 子句参数的情况下是完美的输入。但是,如果至少存在一个,例如 user_name 的那个,那么 Maunil 仍应使用 prepare()execute() 而不是 query(),以避免 MySQL 注入。
    • true 如果他稍后使用结果,例如在网页或其他上显示结果...但他只是在数据库中查找并使用结果计数写入存在(如果发现)...所以在任何地方都没有 mysql 注入的机会
    • 其实没有。在准备 sql 语句时,它不是关于如何使用结果,而是要避免让应用程序用户有机会为参数注入不正确转义的字符串。准备过程确保作为参数值传递的任何内容都被引擎读取为不显眼的正常字符串。
    • 他当然应该首先清理他的变量(只是注意到他没有)...... ups......我只是假设......对OP - 在使用它们之前总是清理你的变量(即使您用户准备的语句)至少使用 mysql_real_escape_string($variable);
    • 是的,在这种情况下使用query 是合法的。注意:当与prepare() 一起使用时,mysql_real_escape_string() 会导致双重转义用户输入,例如到错误的结果。因此,如果使用prepare(),则不应使用mysql_real_escape_string()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-17
    • 1970-01-01
    • 2015-12-31
    • 2021-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多