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

PHP同页提交表单显示提示及防止重复提交解决方案

问题场景
  • 基于POST方法实现同页登录表单提交,服务端校验规则如下:
    • 若用户名字段为空,需在表单顶部展示错误提示:Please enter username.
    • 账号密码校验通过后跳转至dashboard.php,校验不匹配则返回登录页
  • 现有实现存在两个互斥问题:
    • 删除header("location: index.php")跳转逻辑时,错误提示可正常渲染,但刷新页面会触发浏览器的表单重复提交提示
    • 保留跳转逻辑可避免重复提交,但重定向后$error1等提示变量会被重置,错误信息无法正常显示
  • 目标需求:保留header跳转逻辑、规避表单重复提交的前提下,正常展示所有提交后的提示消息
原有问题代码
<?php
session_start();
include("includes/config.php"); 

if(isset($_POST['submit'])){
    
    if (empty($username)){
        $error1 = "Please enter username.";
        header("location: index.php");

    }
    
    $username=mysqli_real_escape_string($con,$_POST['username']);
    $password=mysqli_real_escape_string($con,$_POST['password']);
    
    $sql="select * from admin_user where username='$username' and password='$password'";
    
    $res=mysqli_query($con,$sql);
    if (mysqli_num_rows($res)>0){
        
       session_start();
       $_SESSION["username"] = $username;
       $_SESSION["id"] = $id;
       $_SESSION['admin']['status']= true ;

      header("location: dashboard.php");
    }else{
        $unsucess = "Invalid username or password.";
header("location: index.php");
    }
        
        
}
?>

                    

<?php if(!empty($error1)) {?>
   <p><?php echo $error1; ?></p>
<?php } ?>
                       
                           <form method ="post">
                              <div class="mb-3">
                                 <label for="username" class="form-label">Username*</label>
                                 <input type="text" name="username" class="form-control" id="username" placeholder="Enter username">
                              </div>
                              <div class="mb-3">
                           
                                 <label class="form-label" for="password-input">Password*</label>
                                 <div class="position-relative auth-pass-inputgroup mb-3">
                                    <input type="password" name="password" class="form-control pe-5" placeholder="Enter password" id="password">
                                    <button class="btn btn-link position-absolute end-0 top-0 text-decoration-none text-muted shadow-none" type="button" id="password-addon"><i class="ri-eye-fill align-middle"></i></button>
                                 </div>
                              </div>
                              <div class="mt-4">
                                 <button class="btn btn-success w-100" name="submit" type="submit">Sign In</button>
                              </div>
                   
                           </form>
解决方案

采用Session闪存消息机制实现跨重定向的提示传递,同时修复原有代码的逻辑漏洞,完全遵循PRG(Post/Redirect/Get)模式规避重复提交问题。

核心原理

  • 普通PHP变量生命周期仅存在于单次HTTP请求,重定向会触发全新请求,原请求定义的变量会全部销毁
  • Session是跨请求持久化的存储机制,可用于在重定向后的新请求中读取前序请求存入的提示内容
  • 提示内容读取完成后立刻删除Session中对应的存储字段,保证提示仅展示一次,不会在页面刷新时重复出现
  • 所有header()跳转语句后必须加exit/die终止后续代码执行,避免跳转后的逻辑继续运行引发安全问题

修正后完整代码

<?php
session_start();
include("includes/config.php"); 

// 初始化提示变量
$errorTip = "";

// 处理POST提交逻辑
if(isset($_POST['submit'])){
    // 先获取POST参数,再执行校验(修复原代码先判空、后取参数导致校验失效的问题)
    $username = mysqli_real_escape_string($con, $_POST['username']);
    $password = mysqli_real_escape_string($con, $_POST['password']);
    
    // 用户名为空校验
    if (empty($username)){
        $_SESSION['flash_error'] = "Please enter username.";
        header("location: index.php");
        exit;
    }
    
    // 账号密码校验
    $sql = "select * from admin_user where username='$username' and password='$password'";
    $res = mysqli_query($con, $sql);
    if (mysqli_num_rows($res) > 0){
        $userInfo = mysqli_fetch_assoc($res);
        // 修复原代码$id未定义就存入Session的问题
        $_SESSION["username"] = $username;
        $_SESSION["id"] = $userInfo['id'];
        $_SESSION['admin']['status'] = true;
        header("location: dashboard.php");
        exit;
    }else{
        $_SESSION['flash_error'] = "Invalid username or password.";
        header("location: index.php");
        exit;
    }
}

// 页面渲染前读取闪存提示,读取后立刻删除,实现一次性展示效果
if (!empty($_SESSION['flash_error'])) {
    $errorTip = $_SESSION['flash_error'];
    unset($_SESSION['flash_error']);
}
?>

<!-- 表单顶部错误提示 -->
<?php if(!empty($errorTip)) {?>
   <p class="text-danger"><?php echo $errorTip; ?></p>
<?php } ?>
                       
<form method ="post">
    <div class="mb-3">
        <label for="username" class="form-label">Username*</label>
        <input type="text" name="username" class="form-control" id="username" placeholder="Enter username">
    </div>
    <div class="mb-3">
        <label class="form-label" for="password-input">Password*</label>
        <div class="position-relative auth-pass-inputgroup mb-3">
            <input type="password" name="password" class="form-control pe-5" placeholder="Enter password" id="password">
            <button class="btn btn-link position-absolute end-0 top-0 text-decoration-none text-muted shadow-none" type="button" id="password-addon"><i class="ri-eye-fill align-middle"></i></button>
        </div>
    </div>
    <div class="mt-4">
        <button class="btn btn-success w-100" name="submit" type="submit">Sign In</button>
    </div>
</form>

额外说明:该方案同时修复了原代码中重复调用session_start()、用户名校验逻辑顺序错误、用户ID未从查询结果取值、跳转后未终止执行等隐性问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 12:27:14