注册表单验证优化:提交空字段需留当前页并显示错误
问题描述
点击注册按钮时,若存在空字段,本该显示「用户名或邮箱为必填项」的错误提示,但实际页面会跳转至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
相关产品推荐
相关产品推荐

