PHP 仅以登录形式从 MySQL DB 中获取最后一行

Posted

技术标签:

【中文标题】PHP 仅以登录形式从 MySQL DB 中获取最后一行【英文标题】:PHP only taking the last row from MySQL DB in login form 【发布时间】:2022-01-15 18:56:24 【问题描述】:

我已经在这个问题上停留了 3 天。我正在尝试制作一个登录表单(我已经创建了一个注册表单)并且数据库也在工作。但是现在当我尝试制作登录表单时,我注意到 php 只从数据库中获取最后一行。

从第一张图中可以清楚地看到,我的数据库有 3 条记录。 但是当我尝试登录我的帐户时,它只能让我登录到最近创建的帐户,而不能登录其他帐户。这是我当前的代码:

<div class="login-form">
    <form method="POST">
        <p style="float:left;">
            <input type="email" class="login-input" maxlength="40" name="login-email" id="login-email" placeholder="email" required><span style="color: red;">&nbsp;*</span><br><br>
             <input type="password" class="login-input" maxlength="32" name="login-passw" id="login-passw" placeholder="password" required><span style="color: red;">&nbsp;*</span><br><br>
             <input type="submit" class="btn" name="login-btn">
         </p>
         <?php
         $email = $_POST["login-email"];
         $passw = $_POST["login-passw"];
         $encrypted_passw = md5($passw);

         $sql = "SELECT id, email, passw FROM users";
         $result = $db->query($sql);

         // if (isset($_POST["login-btn"])) 
         //     if ($_POST["login-email"] == $result["email"]) 
         //         echo "<p>Logged in</p>";
         //      else 
         //         echo "<p>wrong</p>";
         //     
         // 
         while ($row = $result->fetch_assoc()) 
             $get_email = $row["email"];
             $get_usr = $row["username"];
             $get_passw = $row["passw"];
         

         if (isset($_POST["login-btn"])) 
             if ($_POST["login-email"] == $get_email && $encrypted_passw == $get_passw) 
                 echo "<p>Logged in</p>";
              else 
                 echo "<p> wrong</p>";
             
        
        ?>
    </form>
</div>

【问题讨论】:

我知道你很兴奋,但请尽量控制你的语言。 Stack Overflow 更像是***而不是 Reddit。 更改您的逻辑以查找电子邮件地址。 '其中电子邮件 = 提供的电子邮件'。然后检查提供的密码和电子邮件是否匹配。您当前正在遍历每一行并每次都覆盖 get_email 因此为什么当您进行比较时它正在比较最后一个结果 请please read this 了解密码哈希。 md5 哈希密码几乎与未哈希密码一样容易破解。 切勿以明文形式或使用 MD5/SHA1 存储密码! 仅存储使用 PHP 的 password_hash() 创建的密码哈希,然后您可以使用 password_verify() 进行验证。看看这篇文章:How to use password_hash 并了解更多关于bcrypt & password hashing in PHP 【参考方案1】:

天啊!我使用的是数组而不是值

<?php            
session_start();
include_once "../php/db_connect.php";
            if (isset($_POST["login-btn"])) 
                
                $email = $_POST["email"];
                $passw = $_POST["passw"];
                $encrypted = md5($passw);
                
                $sql = "SELECT * FROM users WHERE email = '". $email ."'";
                $result = $db->query($sql);
                $get_result = $result->fetch_assoc();

                if ($encrypted == $get_result["passw"]) 
                    echo "<p>Logged in!</p>";
                    $_SESSION["username"] = $get_result["username"];
                    $_SESSION["id"] = $get_result["id"];
                    $_SESSION["email"] = $get_result["email"];
                    Header("Location:../../../");
                 else 
                    echo "<p>Error</p>";
                
            
            ?>

【讨论】:

尝试将其放入电子邮件字段并提交表单。它将删除表中的所有内容。你不能像这样构建有漏洞的应用程序。阅读有关 sql 注入的信息。 '; TRUNCATE users; 警告:您对SQL Injections 持开放态度,应该使用参数化的prepared statements,而不是手动构建查询。它们由PDO 或mysqli 提供。永远不要相信任何形式的输入!即使您的查询仅由受信任的用户执行,you are still in risk of corrupting your data。 Escaping is not enough! 人们,他们不能在电子邮件字段中使用截断用户,因为它被设置为必需的电子邮件输入,因此需要一个 @ 存在 但是为了让大家冷静下来,我把它改成了STMT声明【参考方案2】:

试试这个。首先,我会将 php 代码放在 html 之上。

您只需要收听帖子参数login-btn。将其他帖子数据读入 vars 并在继续之前确认。

当您轮询数据库时,您不需要读取每条记录(假设您有数千条记录,您不想将它们全部拉下来)。只需使用 where 子句过滤提供的电子邮件。

如果电子邮件存在,它将返回带有哈希密码的结果。验证此匹配,您就可以开始了。

您在使用数据库中的最后一条记录时遇到的问题是因为在您的循环中,您每次都覆盖了 var $get_email

<?php
if (isset($_POST["login-btn"])) 

    $email = (isset($_POST["login-email"]) ? $_POST["login-email"] : '');
    $passw = (isset($_POST["login-passw"]) ? $_POST["login-passw"] : '');

    if($email != "" && $passw != "")

        $encrypted_passw = md5($passw);    

        $mysqli = new mysqli('localhost', 'my_user', 'my_password', 'world');
        $stmt = $mysqli->prepare("SELECT email, passw FROM users where email = ?");
        $stmt->bind_param($email);
        $stmt->execute();

        while ($row = $result->fetch_row()) 

            $get_passw = $row["passw"];

            if($encrypted_passw == $row['passw'])
                echo "logged in";
            else
                echo 'no match';
            
        
    
    
?>

<div class="login-form">
    <form method="POST">
        <p style="float:left;">
            <input type="email" class="login-input" maxlength="40" name="login-email" id="login-email" placeholder="email" required><span style="color: red;">&nbsp;*</span><br><br>
            <input type="password" class="login-input" maxlength="32" name="login-passw" id="login-passw" placeholder="password" required><span style="color: red;">&nbsp;*</span><br><br>
            <input type="submit" class="btn" name="login-btn">
        </p>
    </form>
</div>

【讨论】:

现在它甚至不回显结果 想帮助一些有用的调试信息?是否有任何php错误,检查日志等。 @NikkieDev isset 三元调用存在语法错误。我已经更新了代码。您应该在开发/学习时启用错误【参考方案3】:

将您的查询更改为此

"SELECT id, email, passw FROM users where email='".$row["email"]."' 和密码= '".$row["password"]."'"

您不需要对所有行使用 foreach,此查询仅返回您需要的一行

【讨论】:

这是将应用程序暴露给 SQL 注入。 ';截断用户; --

以上是关于PHP 仅以登录形式从 MySQL DB 中获取最后一行的主要内容,如果未能解决你的问题,请参考以下文章

从 DB 获取数据以在下拉 HTML/CSS/MYSQL/PHP 中设置为默认值

从 Postcode DB 获取 lat/lng 并在 PHP/MYSQL 中按最近的顺序排序

使用 PHP 从 MySQL 数据库中获取数据,以表格形式显示以进行编辑

使用php从mysql数据库中获取数据,以所见即所得的形式显示以进行编辑

无法使用 VueJs 从 Mysql DB 获取数据

从 mysql 获取数据并以另一种形式使用