skip to content

PHP: Basic Form Handling in PHP

By popular demand, here are some basic instructions for setting up a form handler in PHP to verify user input and send an email or display an error message in case the validation fails.

Sample HTML Form

Here is the HTML and PHP code for the form we will be working with:

<form method="POST" action="<?PHP echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" accept-charset="UTF-8"> <fieldset> <p>Your Name:<br> <input type="text" size="48" name="name" value="<?PHP if(isset($_POST['name'])) echo htmlspecialchars($_POST['name']); ?>"></p> <p>Email Address:<br> <input type="email" size="48" name="email" value="<?PHP if(isset($_POST['email'])) echo htmlspecialchars($_POST['email']); ?>"></p> <p>Subject<br> <input type="text" size="48" name="subject" value="<?PHP if(isset($_POST['subject'])) echo htmlspecialchars($_POST['subject']); ?>"></p> <p>Enquiry:<br> <textarea name="message" cols="48" rows="8"><?PHP if(isset($_POST['message'])) echo htmlspecialchars($_POST['message']); ?></textarea></p> <p><input type="submit" name="sendfeedback" value="Send Message"></p> </fieldset> </form>

The form will look something like the following - your basic no-frills feedback form:

For testing purposes we've removed all the usual JavaScript Form Validation and HTML5 Form Validation so the form can simply be submitted and validated by PHP on the server.

You'll notice that we've used PHP to insert the form action as the current page. That's because we are using the "redirect-after-POST" technique as illustrated here:

This is explained in more detail in our CAPTCHA article. It prevents the form from being resubmitted if the landing page is reloaded, and allows us to display validation error messages inline using PHP.

Finally, the code includes PHP commands to re-insert any submitted values back in to the form so they don't have to be retyped in case of an error.

PHP Form Handler

The important characteristics of a form handler is that it verifies that the required variables have been set, and that they have appropriate values. Remember to be thorough as this is your last (only real) line of defence against malicious scripts.

Here we are detecting a POST event and extracting the values directly from the PHP $_POST array for testing:

<?PHP // PHP form handler if($_POST && isset($_POST['sendfeedback'], $_POST['name'], $_POST['email'], $_POST['subject'], $_POST['message'])) { $name = $_POST['name']; $email = $_POST['email']; $subject = $_POST['subject']; $message = $_POST['message']; if(!$name) { $errorMsg = "Please enter your Name"; } elseif(!$email || !preg_match("/^\S+@\S+$/", $email)) { $errorMsg = "Please enter a valid Email address"; } elseif(!$message) { $errorMsg = "Please enter your comment in the Message box"; } else { // send email and redirect $to = "feedback@example.com"; if(!$subject) { $subject = "Contact from website"; } $headers = "From: webmaster@example.com" . "\r\n"; mail($to, $subject, $message, $headers); header("Location: http://www.example.com/thankyou.html"); exit; } } ?>

All HTML form elements, aside from unselected checkboxes and radio buttons, will appear in the $_POST array, even if the value is blank. This includes the submit button, which in this case we have named sendfeedback. Naming the button is useful in case there are multiple forms on the page.

The first thing the form handler does is check that all the fields in our form, including the button, appear in the POST array. Then we extract the relevant values for testing.

The testing here is fairly rudimentary. In reality we have special functions for validating email addresses and other data types - as will most JavaScript libraries. We also have more advanced functions for sending email.

For public-facing forms you should add a CAPTCHA or similar device, as you can see in our Feedback form below, or risk being bombarded by spambots.

Placement of the code

The PHP code needs to appear at the top of the page - before any HTML or whitespace is displayed. Otherwise the redirect will fail with the ubiquitous warning "Cannot modify header information - headers already sent".

Your final code should look something like this:

<?PHP // // PHP form handler // ?> <!DOCTYPE html> <html> <head> <title>...</title> ... </head> <body> <form method="POST" action="#" accept-charset="UTF-8"> <fieldset> <!-- html form --> </fieldset> </form> <script> // // javascript form validation code // </script> </body> </html>

It doesn't actually matter where on the page the JavaScript appears, whether inline or as a link.

Displaying Error Messages

When the form is submitted, but not validated, the code execution flows through to the page. All we need to do is check for an error message and display it on the page:

<?PHP if(isset($errorMsg) && $errorMsg) { echo "<p style=\"color: red;\">*",htmlspecialchars($errorMsg),"</p>\n\n"; } ?>

Again, a more advanced version would place the error message next to the affected field, and do this for multiple fields at once. In the demonstration above we've included the error message at the top of the form.

For more advanced validation methods, including a CAPTCHA, or presenting the feedback form in a modal window, you can check out some of the related articles below.

Avoiding Global Variables

In the previous example we made a faux pas in polluting the global variable space. We can avoid this, and make our code more modular and reusable, by calling it as a function:

<?PHP // PHP form handler function validateFeedbackForm($arr) { extract($arr); // name, email, subject, message if(!isset($name, $email, $subject, $message)) { return FALSE; } if(!trim($name)) { return "Please enter your Name"; } if(!preg_match("/^\S+@\S+$/", $email)) { return "Please enter a valid Email address"; } if(!trim($subject)) { $subject = "Contact from website"; } if(!trim($message)) { return "Please enter your comment in the Message box"; } // send email and redirect $to = "feedback@example.com"; $headers = "From: webmaster@example.com" . "\r\n"; mail($to, $subject, $message, $headers); header("Location: http://www.example.com/thankyou.html"); exit; } // script execution starts here if(isset($_POST['sendfeedback'])) { // call form handler $errorMsg = validateFeedbackForm($_POST); } ?>

The extract method turns key/value pairs from the $_POST array into separate variables, but only for the scope of the function.

We could go further and create a form validation class, with separate methods for validating text, email, dates, etc, but that's a project in itself.

The remaining code on the page stays the same:

<form method="POST" action="#" accept-charset="UTF-8"> <fieldset> <?PHP if(isset($errorMsg) && $errorMsg) { echo " <p style=\"color: red;\">*",htmlspecialchars($errorMsg),"</p>\n\n"; } ?> <p>Your Name:<br> <input type="text" size="48" name="name" value="<?PHP if(isset($_POST['name'])) echo htmlspecialchars($_POST['name']); ?>"></p> <p>Email Address:<br> <input type="email" size="48" name="email" value="<?PHP if(isset($_POST['email'])) echo htmlspecialchars($_POST['email']); ?>"></p> <p>Subject<br> <input type="text" size="48" name="subject" value="<?PHP if(isset($_POST['subject'])) echo htmlspecialchars($_POST['subject']); ?>"></p> <p>Enquiry:<br> <textarea name="message" cols="48" rows="8"><?PHP if(isset($_POST['message'])) echo htmlspecialchars($_POST['message']); ?></textarea></p> <p><input type="submit" name="sendfeedback" value="Send Message"></p> </fieldset> </form>

Don't forget to place the PHP code at the top of the page, before any HTML or whitespace.

< PHP

User Comments

Post your comment or question

2 November, 2019

Why check for both $_POST and isset(*)?
($_POST && isset($_POST['sendfeedback']...)

"if($_POST)" is a circuit-breaker to avoid having to make a more expensive check on all the individual fields in case of a $_GET request.

9 July, 2017

I did not notice/see the php url to which the form is supposed to be sent. please help me out!

1 March, 2017

Thank you very much.
This is the clearest exposition of form handlers I've seen.
Much appreciated

4 December, 2015

I like this. I want the redirected message on success to include the validated POST values. How to do that?

The simplest way is to attach them to the redirect URL as GET parameters, but that can have security implications, and there is a limit on length.

$location = "/thankyou.html";
$location .= "?var1=" . urlencode($_POST['var1'])
$location .= "&var2=" . urlencode($_POST['var2'])
$location .= "&var3=" . urlencode($_POST['var3'])
header("Location: $location");
exit;

Otherwise, if you're storing the data submitted in a database, just pass the unique id so the landing page can retrieve it for display.

3 November, 2015

I have an issue when i update form if input type i entered is wrong then page go back to the old value that is entered before and displays error message "enter valid name or address etc". but i want that it displays error "enter valid name address etc" and value does not change, it remains the same that i have given wrong.

3 November, 2015

I've tried out your code and modified it slightly so it would work as an external file. In doing so, I've noticed that the "php validation" only seems to validate the email field and not all of the fields as expected.

Just thought I'd let you know.

other than that, I have to say that this has been a great help and was relieved to find something that is both detailed and helpful.

5 April, 2015

Very helpful!

Just one quick question:

When using PHP in the values for each input field, which is meant to retain user input in case of an error, the values remain displayed even after a successful submission of the form.

How would you reset the form after successful submission to clear all fields?

Thanks.
Michael

I would use Redirect after POST, meaning you first process the POST variables and then redirect (302) to a new page, or the same page with the form blanked.

6 February, 2015

What code can we use to submit the data to a remote server after the validation process?

Thanks in advance.

Bernard Browne

We would normally use cURL (or the PHP cURL library), but it depends on what you're trying to send and what the server will accept.

top