基于用户名的PHP登录页面跳转异常求助(附代码)
登录页面定向跳转问题修复
代码中的核心错误
- 初始登录检查时,
header('Location: $url');使用单引号导致变量无法解析,且$url未定义 - SQL预处理语句缺失参数绑定步骤(
mysqli_stmt_bind_param),直接执行会触发报错 - 重复调用
mysqli_stmt_bind_result,第二次绑定遗漏user_redirect_uri字段,无法获取跳转地址 - 密码验证通过后未添加跳转逻辑,缺少
header()跳转代码 - 重复调用
session_start(),会话初始化只需一次 - SQL查询直接将明文密码作为条件,不符合哈希密码的验证逻辑(应先通过用户名查询哈希密码,再做验证)
修正后的完整代码
<?php // 初始化会话 session_start(); // 检查用户是否已登录,已登录则跳转至对应页面 if(isset($_SESSION["loggedin"]) && $_SESSION["loggedin"] === true){ header("Location: " . $_SESSION["user_redirect_uri"]); exit; } // 引入配置文件 require_once "config.php"; // 定义变量并初始化 $username = $password = ""; $username_err = $password_err = $login_err = ""; // 处理表单提交数据 if($_SERVER["REQUEST_METHOD"] == "POST"){ // 检查用户名是否为空 if(empty(trim($_POST["username"]))){ $username_err = "请输入用户名。"; } else{ $username = trim($_POST["username"]); } // 检查密码是否为空 if(empty(trim($_POST["password"]))){ $password_err = "请输入密码。"; } else{ $password = trim($_POST["password"]); } // 验证凭证 if(empty($username_err) && empty($password_err)){ // 预处理查询语句(仅通过用户名查询,避免密码哈希影响查询结果) $sql = "SELECT id, username, password, user_redirect_uri FROM users WHERE username = ?"; if($stmt = mysqli_prepare($link, $sql)){ // 绑定查询参数 mysqli_stmt_bind_param($stmt, "s", $param_username); // 设置参数值 $param_username = $username; // 执行预处理语句 if(mysqli_stmt_execute($stmt)){ // 存储结果 mysqli_stmt_store_result($stmt); // 检查用户名是否存在,存在则验证密码 if(mysqli_stmt_num_rows($stmt) == 1){ // 绑定结果变量 mysqli_stmt_bind_result($stmt, $id, $username, $hashed_password, $user_redirect_uri); if(mysqli_stmt_fetch($stmt)){ if(password_verify($password, $hashed_password)){ // 密码验证通过,存储会话数据 $_SESSION["loggedin"] = true; $_SESSION["id"] = $id; $_SESSION["username"] = $username; $_SESSION["user_redirect_uri"] = $user_redirect_uri; // 跳转至用户专属页面 header("Location: " . $user_redirect_uri); exit; } else{ // 密码错误提示 $login_err = "用户名或密码错误。"; } } } else{ // 用户名不存在提示 $login_err = "用户名或密码错误。"; } } else{ echo "出错了,请稍后重试。"; } // 关闭语句 mysqli_stmt_close($stmt); } } // 关闭数据库连接 mysqli_close($link); } ?> <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>登录</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <br><br><br> <header><center> <img src = "logo.png" height = "100" width = "180"></center></header> <div class="container"> <div class="row justify-content-center"> <div class="col-md-6"> <div class="card mt-5"> <div class="card-header" style="background-color: #3fbbc0;"> <h4>登录</h4> </div> <div class="card-body"> <?php if(!empty($login_err)){ echo '<div class="alert alert-danger">' . $login_err . '</div>'; } ?> <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post"> <div class="col-md-12 mb-3"> <label>用户名</label> <input type="text" name="username" class="form-control <?php echo (!empty($username_err)) ? 'is-invalid' : ''; ?>" value="<?php echo $username; ?>"> <span class="invalid-feedback"><?php echo $username_err; ?></span> </div> <div class="col-md-12 mb-3"> <label>密码</label> <input type="password" name="password" class="form-control <?php echo (!empty($password_err)) ? 'is-invalid' : ''; ?>"> <span class="invalid-feedback"><?php echo $password_err; ?></span> </div> <div class="form-group"> <center> <input type="submit" class="btn" style="background-color: #3fbbc0; color:#fff;" value="登录"></center> </div> </form> </div> </body> </html>
关键修复说明
- 已登录检查时从
$_SESSION中读取跳转地址,解决未定义变量问题 - 修正SQL预处理逻辑:先绑定参数再执行查询,符合哈希密码的验证流程
- 绑定结果时包含
user_redirect_uri字段,确保能获取用户对应的跳转页面地址 - 密码验证通过后,将跳转地址存入会话并立即执行跳转
- 移除重复的
session_start()调用,避免会话冲突 - 优化前端表单布局,调整间距并修复登录按钮的样式问题
内容的提问来源于stack exchange,提问作者Moon
相关产品推荐
相关产品推荐

