Except if there are any errors, the user must be able to correct them and resubmit the form. Does your logic do that? Using if(the submit button is set){ process the form } else { display the form } doesn’t do this. In fact, the code to process the form data, which should be above the start of the html document, and the code to display the form, which goes inside the html document, are two separate responsibilities.
There are two things you are trying to accomplish - 1) the logic needed to control when the registration form is displayed, and 2) the implementation code for the form processing and the form.
For item #1 - you want to display the form from the point when the visitor navigates to the registration page (if you are doing this on your main index page, you need to make this a separate page), up to the point when the form processing code has completely executed without any errors. Until you have reached this point, you want to display the form, display any errors, and populate the form field values with any existing data.
BTW - the completion of the registration form processing code would include inserting the submitted data into a database table, detecting any duplicate values in unique fields (username and email), and sending the confirmation email that you have cited in the ‘success’ message. I’m not sure if you are leaving this out for now or you don’t know that code to do this is part of the registration process. You would only display the success message after all these things have successfully occurred.
The logic for the form processing should -
- Detect if a post method form has been submitted. You were originally doing this.
- If there is more than one form on a page (which you are not ready to do yet), you would additionally detect which form has been submitted. You would use a hidden form field for this and not the submit button. You cannot guarantee that the submit button will be set for all version of all clients, and it won’t be set if you switch to using ajax to submit the data.
- Keep the submitted form data as an array, then operate on elements of this array throughout the rest of the code.
- Trim all the input data at once. This can be done using one line of code, provided you have done item #3 on this list.
- Validate all the inputs, storing validation error messages in an array, using the field as the array index, so that any depended validation steps can test if there is not already an error for a field and so that you can display the error messages adjacent to the fields they belong with.
- After the end of the validation, if there are no errors (the array holding the error messages will be empty), use the submitted form data, which would include inserting a row of data in a database table and sending the email.
- After all of the above, if there are no errors (inserting the data and sending the email can produce their own errors), redirect to the exact url of the current page to cause a get request for the page. To display the success message after this redirect, store it in a session variable. This session variable is how you can ‘remember’ that the registration process has successfully been completed. You can then use the existence of this session variable to control the display of the form.
See the following example code showing these points -
<?php
session_start();
$post = []; // an array to hold a trimmed working copy of the form data
$errors = []; // an array to hold user/validation error messages
if($_SERVER["REQUEST_METHOD"] == "POST")
{
// trim all the data at once
$post = array_map('trim',$_POST);
// validate inputs (this example only shows two of the inputs) -
// note: php's empty() function considers values to be empty that you may not expect. if you are specifically testing for empty strings, you should use that as your test condition
if($post['username'] === '')
{
// store error messages in the $errors array using the field name as the index
$errors['username'] = 'Required';
}
if($post['password'] === '')
{
$errors['password'] = 'Required';
}
// the rest of the validation logic would go here...
// if there are no errors, use the submitted form data
if(empty($errors))
{
// you would build and execute a prepared INSERT query here...
// any column that must be unique (username, email) is defined as a unique index
// to detect duplicate values, you would test if the query produced a duplicate index error
// if there's only one unique index, the duplicate is in that column
// if you have more than one unique index, you would then query to find which column(s) contain duplicate values
// you would add error messages to the $errors array for any duplicate values
// if there are no errors at this point, you would build and send the confrontation email
}
// if no errors at this point, success
if(empty($errors))
{
// fake some values that will be in the final code
$post['first_name'] = 'first name'; // note: most people have at least a first and last name, not just a name
$post['email'] = '[email protected]';
// put the success message in a session variable
$_SESSION['register'] = "Thank you for registering, {$post['first_name']}. You can now login with your username, {$post['username']}. A confirmation email has been sent to {$post['email']}.";
// redirect to the exact same url of this page to cause a get request - Post, Redirect, Get (PRG)
die(header("Refresh:0"));
}
}
?>
<style>
.er {
background-color: white;
color: red;
}
</style>
<?php
// display the registration form
if(!($_SESSION['register'] ?? false))
{
?>
<form method="post">
<label>Username: <input type="text" name="username" value="<?php echo htmlentities($post['username'] ?? '',ENT_QUOTES); ?>">
<span class='er'>* <?php echo htmlentities($errors['username'] ?? '',ENT_QUOTES);?></span></label><br>
<label>Password: <input type="password" name="password" value="<?php echo htmlentities($post['password'] ?? '',ENT_QUOTES); ?>">
<span class='er'>* <?php echo htmlentities($errors['password'] ?? '',ENT_QUOTES);?></span></label><br>
<input type="submit"><br>
</form>
<?php
}
else
{
// display the registration success message
echo htmlentities($_SESSION['register'],ENT_QUOTES);
}
?>