You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP面向对象mysqli预处理语句登录校验失效问题求助

编辑说明:版主标记为“已有答案”的问题并未解答本疑问,Chris Haas给出了有效解答。

运行代码时持续返回用户名或密码无效提示,核心逻辑存在多处疏漏,原始代码如下:

<?php
$configs = include('../hidden/config.php');

echo 'Hello from jslogin.php';

if(isset($_POST)){

    /* Login values from user */
    $username   = $_POST['username'];
    $password   = password_hash($_POST['password'], PASSWORD_DEFAULT);

    /* Define DB variables */
    $db_host        = $configs['db_host'];
    $db_user        = $configs['db_user'];
    $db_password    = $configs['db_password'];
    $db_name        = $configs['db_name'];

    /* Connect to DB */
    $dbc = new mysqli($db_host, $db_user, $db_password, $db_name) 
    or die('Error connecting to Database.');

    /* Prepare and bind the statements */
    $stmt = $dbc->prepare("SELECT first_name FROM user_reg where username=? AND password=?");
    $stmt->bind_param("ss", $username, $password);

    /* Execute prepared statements and interpolate parameterized values*/
    $stmt->execute();

    /* Get result and number of rows returned */
    $result = $stmt->get_result();
    $count = $result->num_rows;

    /* Check to see if statement returned 1 row and pass/fail accordingly and grab firstname*/
    if($count == 1){
        $firstname = $result;
        alert("$firstname Successfully Logged In.");
    }else
    {
        echo 'You need to enter a valid username and/or password!!!';
    }

}
问题根源
  • 核心密码校验逻辑错误:password_hash() 每次执行会自动生成随机盐,相同明文密码多次哈希得到的结果完全不同。登录阶段直接对用户输入的密码做哈希,再和数据库注册时存储的哈希值做SQL等值匹配,永远无法匹配成功。
  • 入口判断无效:isset($_POST) 恒返回真,即使没有POST请求提交也会进入登录逻辑,应该判断具体的用户名、密码提交字段是否存在。
  • 函数调用错误:PHP无内置alert()函数,该函数是前端JavaScript方法,直接在PHP中调用会触发未定义函数报错。
  • 结果读取错误:登录成功分支直接把mysqli结果对象赋值给$firstname变量,没有调用fetch方法从结果集中取出实际字段值,拿不到用户姓名。
  • 错误处理不合理:数据库连接使用or die()写法会屏蔽mysqli的详细错误信息,不利于排查问题。
修正后可运行代码
<?php
$configs = include('../hidden/config.php');

echo 'Hello from jslogin.php';

// 仅在用户名、密码字段都提交时进入登录逻辑
if(isset($_POST['username'], $_POST['password'])){

    /* 接收用户提交参数 */
    $username   = trim($_POST['username']);
    $password   = $_POST['password']; // 登录阶段不要直接哈希用户输入的明文密码

    /* 读取数据库配置 */
    $db_host        = $configs['db_host'];
    $db_user        = $configs['db_user'];
    $db_password    = $configs['db_password'];
    $db_name        = $configs['db_name'];

    /* 连接数据库,开启异常模式方便排错 */
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $dbc = new mysqli($db_host, $db_user, $db_password, $db_name);
    $dbc->set_charset('utf8mb4');

    /* 仅根据用户名查询对应记录,不要在SQL中做密码匹配 */
    $stmt = $dbc->prepare("SELECT first_name, password FROM user_reg where username=?");
    $stmt->bind_param("s", $username);
    $stmt->execute();
    $result = $stmt->get_result();
    $user = $result->fetch_assoc();

    // 先校验用户是否存在,再用password_verify验证密码哈希
    if($user && password_verify($password, $user['password'])){
        $firstname = $user['first_name'];
        // 输出JS弹窗需要拼接完整的script标签
        echo "<script>alert('{$firstname} Successfully Logged In.');</script>";
    }else
    {
        echo 'You need to enter a valid username and/or password!!!';
    }
}
关键实现说明
  • 注册用户时,必须使用password_hash($用户输入的明文密码, PASSWORD_DEFAULT)生成哈希值后存入数据库,禁止存储明文密码。
  • 登录阶段禁止在SQL语句中做密码等值匹配,先通过用户名查出对应存储的哈希值,再传入password_verify()做校验。
  • 预处理语句已经可以防范SQL注入风险,不需要额外对用户输入做转义处理。

内容的提问来源于stack exchange,提问作者user2654953

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 17:57:25