如何在不跳转页面的情况下显示表单错误并保留用户输入内容?
Got it, let's tackle this problem head-on. The core issues here are that your current setup redirects away on validation failure (losing all user input) and dumps errors on a separate page. We'll fix this by keeping everything on one page, showing errors inline, and preserving what the user already typed.
Here's the step-by-step solution with updated code:
1. Merge PHP Logic & Form into One File
First, move your registration processing code into the top of registration.php (the file with your form). This way, we can handle submission, validation, and display all in one place without redirects.
2. Track Errors & Preserve Input
We'll use an array to store error messages for each field, and populate the form inputs with the user's submitted values if validation fails.
3. Secure Your SQL Query
Your original code is vulnerable to SQL injection—we'll fix that with prepared statements, which are safer and more reliable.
Updated Full Code (registration.php)
<?php require 'db_connect.php'; $errors = []; $username = ''; $email = ''; if ($_SERVER['REQUEST_METHOD'] === 'POST') { // Sanitize and get input values $username = trim($_POST['username']); $email = trim($_POST['email']); $password = trim($_POST['password']); // Validate username if (empty($username)) { $errors['username'] = 'Please enter a username'; } elseif (strlen($username) > 25) { $errors['username'] = 'Username must be less than 25 characters'; } // Validate email if (empty($email)) { $errors['email'] = 'Please enter an email'; } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) { $errors['email'] = 'Please enter a valid email address'; } // Validate password if (empty($password)) { $errors['password'] = 'Please enter a password'; } // If no errors, process registration if (empty($errors)) { $hashword = password_hash($password, PASSWORD_DEFAULT); // Use prepared statement to prevent SQL injection $query = "INSERT INTO member (username, password, email) VALUES (?, ?, ?)"; $stmt = mysqli_prepare($connection, $query); mysqli_stmt_bind_param($stmt, "sss", $username, $hashword, $email); if (mysqli_stmt_execute($stmt)) { // Redirect to login only after successful registration (no output before header!) header('Location: login.html'); exit; // Always exit after header redirect } else { $errors['general'] = 'Registration failed: ' . mysqli_error($connection); } } } ?> <!doctype html> <html lang="en"> <head> <title>Gumby template file</title> <meta charset="utf-8" /> <script data-touch="gumby/js/libs" src="gumby/js/libs/gumby.min.js"></script> <script src="gumby/js/libs/jquery-2.0.2.min.js"></script> <link rel="stylesheet" href="gumby/css/gumby.css"> <script src="gumby/js/libs/modernizr-2.6.2.min.js"></script> <link rel="stylesheet" href="forumhomepage_style.css"> <link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet"> <style> /* Optional: Style error messages to make them stand out */ .error { color: #dc3545; font-size: 0.875em; margin-top: 0.25em; } </style> </head> <body> <?php if (!empty($errors['general'])): ?> <div class="error"><?php echo $errors['general']; ?></div> <?php endif; ?> <form name="register" action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" method="post"> <table> <tr> <td>Username: </td> <td> <input type="text" name="username" maxlength="25" value="<?php echo htmlspecialchars($username); ?>" /> <?php if (isset($errors['username'])): ?> <div class="error"><?php echo $errors['username']; ?></div> <?php endif; ?> </td> </tr> <tr> <td>Email: </td> <td> <input type="email" name="email" id="email" value="<?php echo htmlspecialchars($email); ?>" /> <?php if (isset($errors['email'])): ?> <div class="error"><?php echo $errors['email']; ?></div> <?php endif; ?> </td> </tr> <tr> <td>Password: </td> <td> <input type="password" name="password" /> <?php if (isset($errors['password'])): ?> <div class="error"><?php echo $errors['password']; ?></div> <?php endif; ?> </td> </tr> <tr> <td> </td> <td><input type="submit" value="Register" /></td> </tr> </table> </form> </body> </html>
Key Changes Explained:
- Single File Handling: All logic is in
registration.php, so submission doesn't redirect away—errors and input stay on the same page. - Error Tracking: The
$errorsarray stores messages for each field, which are displayed right next to the relevant input for clarity. - Preserved Input: Each text/email input uses
value="<?php echo htmlspecialchars($username); ?>"to repopulate the user's input after submission. We usehtmlspecialchars()to prevent XSS attacks. - Secure SQL: Prepared statements (
mysqli_prepare,mysqli_stmt_bind_param) eliminate SQL injection risks—never concatenate user input directly into SQL queries! - Proper Redirect: We only redirect to
login.htmlafter successful registration, and useexitimmediately afterheader()to stop further script execution (critical, since output beforeheader()causes PHP errors). - Better Validation: Added email format check with
filter_var()and username length validation directly in the error logic.
Why Your Original Code Failed:
- You were redirecting on validation failure, which clears all POST data (hence lost input).
- You tried to use
header()after echoing content—this causes PHP errors because headers must be sent before any output. - Error messages were printed in a separate context, not tied to the form fields.
内容的提问来源于stack exchange,提问作者user9161375

