如何通过PHP在同一登录页面显示错误提示并完成登录校验
改造方案
核心调整逻辑:
- 取消独立的
authentication.php处理页,将后端校验逻辑和登录表单合并到同一个文件,提交时请求当前页即可实现错误原位展示 - 用错误收集数组统一存储所有校验不通过的提示,渲染表单时直接输出
- 修复原有代码的校验逻辑bug,所有校验项按顺序判断,任意一项不通过就终止后续流程,不会提前查询数据库或放行登录
- 补充SQL参数化查询逻辑,修复原代码直接拼接参数存在的SQL注入风险
- 所有校验全部通过后才写入登录会话、跳转到用户中心页
改完的完整单文件代码(文件名可设为login.php,替换原有两个分离的文件即可)
<?php session_start(); include("connection.php"); $errors = []; // 统一存储错误提示 // 提交表单时才走校验逻辑 if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['submit'])) { // 1. 接收并基础校验输入参数 $uname = trim($_POST['user'] ?? ''); $upassword = trim($_POST['pass'] ?? ''); $Company_code = trim($_POST['pos'] ?? ''); $captchaResp = $_POST['g-recaptcha-response'] ?? ''; if (empty($uname)) $errors[] = "请输入用户名"; if (empty($upassword)) $errors[] = "请输入密码"; if (empty($Company_code)) $errors[] = "请输入企业代码"; if (empty($captchaResp)) $errors[] = "请完成人机验证"; // 2. 没有基础输入错误时,校验reCAPTCHA if (empty($errors)) { $secretkey = "6Lcl4eQgAAAAAN4z4GC-UzfpLNYzlgoPINnHiovj"; $ip = $_SERVER['REMOTE_ADDR']; $url = "https://www.google.com/recaptcha/api/siteverify?secret=$secretkey&response=$captchaResp&remoteip=$ip"; $fire = file_get_contents($url); $data = json_decode($fire); if (!$data->success) { $errors[] = "人机验证未通过,请重试"; } } // 3. 校验企业代码 if (empty($errors) && $Company_code !== 'CDSL') { $errors[] = "企业代码无效"; } // 4. 前面校验全通过,才查数据库校验账号密码 if (empty($errors)) { // 用参数化查询,避免SQL注入 $sql = "SELECT * FROM user_master WHERE UM_USERNAME = ? AND um_pwd = ?"; $params = [$uname, $upassword]; $res = sqlsrv_query($conn, $sql, $params); $result = sqlsrv_fetch_array($res, SQLSRV_FETCH_ASSOC); if (!$result) { $errors[] = "用户名或密码错误"; } } // 5. 所有校验全通过,写入登录状态跳转 if (empty($errors)) { $_SESSION['login_user'] = $uname; header("location:my-account.php"); exit; } } ?> <html> <head> <title>Simple login script using php</title> <!-- 引入reCAPTCHA依赖JS,原代码漏写会导致验证组件不加载 --> <script src="https://www.google.com/recaptcha/api.js" async defer></script> </head> <body> <!-- 错误提示统一输出位置 --> <?php if (!empty($errors)): ?> <div style="color:red;margin:10px 0;"> <?php foreach ($errors as $err): ?> <p><?php echo $err; ?></p> <?php endforeach; ?> </div> <?php endif; ?> <!-- action留空即提交到当前页 --> <form name="f1" action="" onsubmit="return validation()" method="POST"> <input type="text" name="user" value="<?php echo htmlspecialchars($_POST['user'] ?? ''); ?>" placeholder="用户名"> <input type="password" name="pass" placeholder="密码"> <input type="text" name="pos" value="<?php echo htmlspecialchars($_POST['pos'] ?? ''); ?>" placeholder="企业代码"> <div class="g-recaptcha" data-sitekey="6Lcl4eQgAAAAANX3sCFxUJETS6Q75uGRKZzzBjc"></div> <input type="submit" id="btn" value="Login" name="submit"/> </form> </body> </html>
额外说明
- 输入框保留了用户已填内容的回显,校验失败后不用重复输入所有内容
- 校验顺序从易到难:先校验非空、再做人机验证、再校验企业代码、最后查询数据库,减少不必要的资源请求
- 原代码中reCAPTCHA校验失败时错误将登录状态设为允许的逻辑bug已经修复,任意一项不通过都会直接拦截
内容的提问来源于stack exchange,提问作者user19492179
相关产品推荐
相关产品推荐

