如何让PHP注册验证错误信息显示在对应HTML表单输入框下方?
如何将注册表单的错误信息显示在对应输入框下方
要实现错误信息精准对应到输入框下方显示,核心是先收集所有错误,再在表单的对应位置输出,而非直接用exit中断脚本。以下是具体修改方案和完整代码:
关键修改思路
- 重构PHP校验逻辑:将PHP代码移到页面顶部,创建
$errors数组按字段存储错误,避免终止脚本 - 添加错误显示区域:在每个注册输入框的容器内,插入对应字段的错误输出代码
- 优化用户体验:保留用户提交的输入内容,用Bootstrap样式美化错误信息
- 修复原代码bug:修正变量名错误、正则表达式错误及冗余数据库操作
修改后的完整代码
<?php include 'config.php'; $errors = []; $success = ''; // 仅在提交注册表单时处理逻辑 if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['Rusername'], $_POST['Rpassword'], $_POST['Remail'])) { // 检查字段是否为空 if (empty($_POST['Rusername'])) { $errors['username'] = '请输入用户名'; } if (empty($_POST['Rpassword'])) { $errors['password'] = '请输入密码'; } if (empty($_POST['Remail'])) { $errors['email'] = '请输入邮箱'; } // 邮箱格式校验 if (!empty($_POST['Remail']) && !filter_var($_POST['Remail'], FILTER_VALIDATE_EMAIL)) { $errors['email'] = '邮箱格式无效'; } // 用户名格式校验 if (!empty($_POST['Rusername']) && preg_match('/^[a-zA-Z0-9]+$/', $_POST['Rusername']) == 0) { $errors['username'] = '用户名只能包含字母和数字'; } // 密码长度校验 $password = $_POST['Rpassword'] ?? ''; if (!empty($password) && (strlen($password) > 26 || strlen($password) < 14)) { $errors['password'] = '密码长度必须在14-26位之间'; } // 密码强度校验 if (!empty($password)) { $uppercase = preg_match('@[A-Z]@', $password); $lowercase = preg_match('@[a-z]@', $password); $number = preg_match('@[0-9]@', $password); $specialchars = preg_match('@[^\w]@', $password); if (!$uppercase || !$lowercase || !$number || !$specialchars) { $errors['password'] = '密码强度不足,必须包含至少1个大写字母、1个小写字母、1个数字和1个特殊字符'; } } // 无错误时执行注册逻辑 if (empty($errors)) { // 检查用户名是否已存在 if ($stmt = $con->prepare('SELECT id FROM accounts WHERE username = ?')) { $stmt->bind_param('s', $_POST['Rusername']); $stmt->execute(); $stmt->store_result(); if ($stmt->num_rows > 0) { $errors['username'] = '用户名已存在,请更换'; } else { // 插入新用户 $hashedPassword = password_hash($_POST['Rpassword'], PASSWORD_DEFAULT); if ($stmt = $con->prepare('INSERT INTO accounts (username, password, email) VALUES (?, ?, ?)')) { $stmt->bind_param('sss', $_POST['Rusername'], $hashedPassword, $_POST['Remail']); if ($stmt->execute()) { $success = '注册成功!现在可以登录了'; } else { $errors['general'] = '注册失败,请重试'; } } else { $errors['general'] = '数据库准备语句失败'; } } $stmt->close(); } else { $errors['general'] = '数据库准备语句失败'; } $con->close(); } } ?> <!doctype html> <html lang="en"> <head> <title>Home</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <link rel="stylesheet" href="https://unicons.iconscout.com/release/v2.1.9/css/unicons.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css"> <link rel="stylesheet" href="styles.css"> </head> <body> <div class="section"> <div class="container"> <div class="row full-height justify-content-center"> <div class="col-12 text-center align-self-center py-5"> <div class="section pb-5 pt-5 pt-sm-2 text-center"> <!-- 全局成功/错误提示 --> <?php if ($success): ?> <div class="text-success mb-3"><?php echo $success; ?></div> <?php endif; ?> <?php if (isset($errors['general'])): ?> <div class="text-danger mb-3"><?php echo $errors['general']; ?></div> <?php endif; ?> <h6 class="mb-0 pb-3"><span>Log In </span><span>Sign Up</span></h6> <input class="checkbox" type="checkbox" id="reg-log" name="reg-log"/> <label for="reg-log"></label> <div class="card-3d-wrap mx-auto"> <div class="card-3d-wrapper"> <div class="card-front"> <div class="center-wrap"> <div class="section text-center"> <h4 class="mb-4 pb-3">Log In</h4> <div class="login"> <form target="_self" method="post" autocomplete="off"> <div class="form-group"> <input type="email" id="Lemail" name="Lemail" class="form-style" placeholder="Email"> <i class="input-icon uil uil-at"></i> </div> <div class="form-group mt-2"> <input type="password" id="Lpassword" name="Lpassword" class="form-style" placeholder="Password"> <i class="input-icon uil uil-lock-alt"></i> </div> <input type="submit" value="Login" class="btn mt-4"> </form> </div> <p class="mb-0 mt-4 text-center"><a href="Link-to-page.com" class="link">Forgot your password?</a></p> </div> </div> </div> <div class="card-back"> <div class="center-wrap"> <div class="section text-center"> <div class="register"> <h4 class="mb-3 pb-3">Sign Up</h4> <form target="_self" method="post" autocomplete="off"> <div class="form-group"> <input type="text" id="Rusername" name="Rusername" class="form-style" placeholder="Username" value="<?php echo $_POST['Rusername'] ?? ''; ?>"> <i class="input-icon uil uil-user"></i> <!-- 用户名错误信息 --> <?php if (isset($errors['username'])): ?> <small class="text-danger d-block mt-1"><?php echo $errors['username']; ?></small> <?php endif; ?> </div> <div class="form-group mt-2"> <input type="email" id="Remail" name="Remail" class="form-style" placeholder="Email" value="<?php echo $_POST['Remail'] ?? ''; ?>"> <i class="input-icon uil uil-at"></i> <!-- 邮箱错误信息 --> <?php if (isset($errors['email'])): ?> <small class="text-danger d-block mt-1"><?php echo $errors['email']; ?></small> <?php endif; ?> </div> <div class="form-group mt-2"> <input type="password" id="Rpassword" name="Rpassword" class="form-style" placeholder="Password"> <i class="input-icon uil uil-lock-alt"></i> <!-- 密码错误信息 --> <?php if (isset($errors['password'])): ?> <small class="text-danger d-block mt-1"><?php echo $errors['password']; ?></small> <?php endif; ?> </div> <input type="submit" value="Register" class="btn mt-4"> </form> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </body> </html>
核心优化点说明
- 错误精准映射:通过
$errors['字段名']的方式存储错误,在对应输入框下方判断输出,实现错误信息与输入框一一对应 - 保留用户输入:在用户名、邮箱输入框添加
value="<?php echo $_POST['字段名'] ?? ''; ?>",避免用户提交错误后丢失已填内容 - 逻辑去冗余:合并重复的数据库prepare操作,先检查用户名是否存在再执行插入,提升代码效率
- 样式美化:用Bootstrap的
text-danger类将错误信息显示为红色,d-block确保错误信息独占一行
内容的提问来源于stack exchange,提问作者Naveelea
相关产品推荐
相关产品推荐

