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

注册表单验证优化:提交空字段需留当前页并显示错误

问题描述

点击注册按钮时,若存在空字段,本该显示「用户名或邮箱为必填项」的错误提示,但实际页面会跳转至index.php,需重新点击按钮打开表单才能看到错误。需求是:用户提交空字段时停留在注册页面,直接显示错误提示且自动打开注册表单。

解决方案

1. 调整PHP验证逻辑,补充空字段提示与跳转参数

修改signup-logic.php,优先检测空字段,同时在跳转时携带参数告知前端自动打开注册表单:

require 'config/database.php';

session_start(); // 确保开启会话

if(isset($_POST['submit'])) {
    $post_data = $_POST;
    $email = filter_var($post_data['email'], FILTER_VALIDATE_EMAIL);
    $username = filter_var($post_data['username'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
    $createpassword = filter_var($post_data['createpassword'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
    $confirmpassword = filter_var($post_data['confirmpassword'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
    
    // 优先检测空字段
    if(empty($post_data['email']) || empty($post_data['username'])) {
        $_SESSION['signup'] = '用户名或邮箱为必填项';
    } else if(!$email) {
        $_SESSION['signup'] = '请输入有效的邮箱地址';
    } else if(strlen($username) < 3) {
        $_SESSION['signup'] = '用户名长度不能少于3位';
    } else if (strlen($createpassword) < 8 || strlen($confirmpassword) < 8) {
        $_SESSION['signup'] = '密码长度需不少于8位';
    } else {
        if($createpassword !== $confirmpassword) {
            $_SESSION['signup'] = '两次输入的密码不匹配';
        } else {
            $hashed = password_hash($createpassword, PASSWORD_DEFAULT);
            // 注意:此处存在SQL注入风险,建议改用预处理语句
            $user_chk_query = "SELECT * FROM users WHERE username = '$username' OR email = '$email'";
            $user_chk_result = mysqli_query($conn, $user_chk_query);
            if(mysqli_num_rows($user_chk_result) > 0) {
                $_SESSION['signup'] = "用户名或邮箱已存在";
            }
        }
    }

    if(isset($_SESSION['signup'])) {
        $_SESSION['signup-data'] = $post_data;
        // 跳转时携带参数,告知前端打开注册表单
        header('location: '. ROOT_URL . 'index.php?show_register=1');
        die();
    } else {
        // 插入用户数据(建议改用预处理语句防止SQL注入)
        $insert_query = "INSERT INTO users SET email = '$email', username = '$username', password = '$hashed'";
        $insert_user = mysqli_query($conn,$insert_query);

        if(!mysqli_error($conn)) {
            $_SESSION['signup-success'] = '注册成功,请登录';
            header('location: '. ROOT_URL . 'index.php?show_register=0');
           die();
        } else {
            $_SESSION['signup'] = '注册失败,请稍后重试';
            $_SESSION['signup-data'] = $post_data;
            header('location: '. ROOT_URL . 'index.php?show_register=1');
            die();
        }
    }
} else {
    header('location: '. ROOT_URL . 'index.php');
    die();
}

2. 优化前端HTML,实现数据回显与自动打开表单

修改index.php中的注册表单,添加数据回显逻辑,并通过JS监听URL参数自动打开注册表单:

<form action="<?= ROOT_URL ?>signup-logic.php" method="POST">
    <div class="popup-form" id="my-form">
        <div class="form-box">
            <i id="my-close-btn" class="uil uil-multiply"></i>
            <div class="button-box">
                <div id="btn"></div>
                <button id="log-btn" class="toggle-btn" type="button">登录</button>
                <button id="reg-btn" class="toggle-btn" type="button">注册</button>
            </div>
            <div class="social-icons">
                <a href="#"><i class="fa-brands fa-twitter"></i></a>
                <a href="#"><i class="fa-brands fa-facebook"></i></a>
                <a href="#"><i class="fa-brands fa-google"></i></a>
            </div>
            <div id="login" class="form-group">
                <input type="text" class="input-field" placeholder="用户名">
                <input type="password" class="input-field" placeholder="密码">
                <input type="checkbox" id="rem-chk" class="check-box"><span class="rem">记住我</span>
                <button type="submit" class="submit-btn">登录</button>
                <p id="r_msg">注册成功,请登录</p>
            </div>
            <div id="register" class="form-group">
                <?php if (isset($_SESSION['signup'])) : ?>
                    <div class="err_msg">
                        <p id="g_msg">
                            <?= $_SESSION['signup']; ?>
                        </p>
                    </div>
                    <?php 
                        unset($_SESSION['signup']);
                        if(isset($_SESSION['signup-data'])) unset($_SESSION['signup-data']);
                    ?>
                <?php endif ?>
                <!-- 表单数据回显 -->
                <input type="email" name="email" value="<?= isset($_SESSION['signup-data']['email']) ? htmlspecialchars($_SESSION['signup-data']['email']) : '' ?>" class="input-field" placeholder="邮箱">
                <input type="text" name="username" value="<?= isset($_SESSION['signup-data']['username']) ? htmlspecialchars($_SESSION['signup-data']['username']) : '' ?>" class="input-field" placeholder="用户名">
                <!-- 密码字段不回显,保障安全 -->
                <input type="password" name="createpassword" value="" class="input-field" placeholder="设置密码">
                <input type="password" name="confirmpassword" value="" class="input-field" placeholder="确认密码">
                <div class="type-chk">
                    <input type="checkbox" class="check-box">
                    <span class="i-agree">我同意服务条款与隐私政策</span>
                </div>
                <button type="submit" name="submit" class="submit-btn">注册</button>
            </div>
        </div>
    </div>

    <button class="pro-btn" type="button" id="my-form-btn">点击推广你的网站</button>
</form>

<script>
// 页面加载时自动打开注册表单
window.addEventListener('load', function() {
    const urlParams = new URLSearchParams(window.location.search);
    const form = document.getElementById('my-form');
    const regBtn = document.getElementById('reg-btn');

    if(urlParams.has('show_register') && urlParams.get('show_register') === '1') {
        form.style.display = 'block';
        regBtn.click(); // 触发注册标签切换
        form.scrollIntoView({ behavior: 'smooth' }); // 滚动到表单位置
    }
});

// 表单切换逻辑
document.getElementById('log-btn').addEventListener('click', function() {
    document.getElementById('login').style.display = 'block';
    document.getElementById('register').style.display = 'none';
});

document.getElementById('reg-btn').addEventListener('click', function() {
    document.getElementById('login').style.display = 'none';
    document.getElementById('register').style.display = 'block';
});

// 关闭表单逻辑
document.getElementById('my-close-btn').addEventListener('click', function() {
    document.getElementById('my-form').style.display = 'none';
});
</script>

3. 安全与体验补充说明

  • SQL注入防护:当前PHP代码直接拼接用户输入到SQL语句中,存在安全风险,建议改用mysqli预处理语句或PDO执行数据库操作。
  • 密码安全:密码输入框使用type="password"而非text,且验证失败后不回显密码内容。
  • 会话管理:确保所有涉及SESSION的页面都调用了session_start(),否则SESSION变量无法正常生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 19:47:34