By Iain Tench

Form Validation with PHP

By Iain Tench

In this article you’ll construct and validate a simple form using HTML and PHP. The form is created using HTML and validation and processing of the form’s contents is done with PHP. The goal is to teach you some basic HTML form elements and how their data is accessible to you in your PHP scripts.

The form you’ll create contains a number of inputs: text fields, radio buttons, a multiple-option select list, a checkbox, and a submit button. These inputs will be validated to ensure, for example, that the user has entered their name. Any errors or omissions will be highlighted with a message alongside the relevant field.

The HTML Form

First, let’s look at the form. The purpose of the form is to capture user details (name, address, and email) to obtain feedback (on fruit consumption and favorite fruit) and request a brochure.

Text Fields

The name, address, and email fields are text input elements and can be coded like this:

Name <input type="text" name="name" value="">
Address <input type="text" name="address" value="">
Email <input type="text" name="email" value="">

The HTML input element can have several attributes, the most important of which are the type and name attributes. type="text" defines these instances as a single-line input field to accept text. The name attribute is used to specify a name for this value.

Radio Buttons

<input type="radio" name="howMany" value="zero"> 0
<input type="radio" name="howMany" value="one"> 1
<input type="radio" name="howMany" value="two"> 2
<input type="radio" name="howMany" value="twoplus"> More than 2

Here type="radio" renders the input as a radio button. Notice how each button is assigned the same name. This is because collectively the radio buttons should be treated as a group (the user should select either 0, or 1, or 2, etc.). The value attribute differs for each button to provide the different selections that can be made.

Select List

<select name="favFruit[]" size="4" multiple>
 <option value="apple">Apple</option>
 <option value="banana">Banana</option>
 <option value="plum">Plum</option>
 <option value="pomegranate">Pomegranate</option>
 <option value="strawberry">Strawberry</option>
 <option value="watermelon">Watermelon</option>

In this case, the name attribute of the select element is given as an array (with square brackets) because multiple choices are allowed (because of the presence of the multiple attribute). Without multiple, only one option would be selectable.

Each option specified within the select has a distinct value. The value attribute for each option element is the value that will be submitted to the server, and the text between the opening and closing option tag is the value the user will see in the menu.


<input type="checkbox" name="brochure" value="Yes">

The input is presented as a checkbox. Its value will be set to “Yes” if the box has been checked.

Submit Button

<input type="submit" name="submit" value="Submit">

Last but not least there is the submit button. Its value is presented as its label, and clicking on it will trigger the form submission.

The Form Element

There are two specific attributes that need to be set in the form tag, action and method:

<form method="POST"
 action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">

htmlspecialchars() is used here to convert specific HTML characters to their HTML entity names, e.g. > will be converted to &gt;. This prevents the form from breaking if the user submits HTML markup and also is a means of protecting against XSS (Cross Site Scripting) attacks, which attackers will use to try to exploit vulnerabilities in web applications.

action defines where the form contents are sent when the form is submitted; in this case, the value of $_SERVER["PHP_SELF"].

$_SERVER is an array with entries filled in at PHP run time; the PHP_SELF key contains the filename of the PHP script that is being executed. Using $_SERVER["PHP_SELF"] is preferable to simply hard-coding a location if you want your form to post back to the same script that generated it since you won’t have to update the code if you change the script’s name.

method determines how the form’s contents is submitted. POST means that the form’s content is sent as part of the HTTP request’s body. The values are then retrievable in PHP using the $_POST array.

The alternative to POST is GET which passes the form’s values as part of the URL. Values sent using GET are retrievable in PHP using $_GET. The main difference between the methods POST and GET is visibility. There are numerous articles on the web about choosing between them, but my advise is to stick to POST when using forms unless you have a good reason to pass user data in a viewable URL.

Remember that when working with HTML forms:

  • All of the form controls must be enclosed within the form tags.
  • The alignment of text and form controls can be achieved in many ways. CSS is the preferred option for many, but be prepared to see tables used for alignment in older HTML.
  • Not discussed here, but important for accessibility is the label element.

Form Processing

Now that you’ve defined the form in HTML, let’s identify the two stages the form goes through – when the blank form is loaded, and when the user has completed the form and clicks the submit button. The script needs to be able to differentiate between the two stages so the form behaves properly.

To determine whether the form has been submitted by the user, either check the request method (an example follows in the next section) or check for the presence of a specific form control (usually the submit button).

Whichever method you use, if the form has been submitted, it should be validated. If it has not been submitted, bypass the validation and display a blank form.

Capturing the Form Contents

So far, we have a largely HTML page which defines the form; the only PHP so far is to specify the form’s action value. We need to add code which will pick up the form data and allow us to check it and create error messages if needed.

At the start of the script, before any HTML, you can check whether the form has been submitted using $_SERVER["REQUEST_METHOD"]. If the REQUEST_METHOD is POST, then you know the script has been submitted.

Detecting a form submission is a little bit trickier when you’re using GET, because just requesting the page to view the form will probably happen as a GET request as well. One common work around is provide a name attribute to the submit button, and check whether it is set in the $_GET array with isset(). For example:

<input type="submit" name="submit" value="Submit">
if (isset($_GET["submit"])) {
    // process the form contents...

Validating the Form Contents

When the form is submitted, the following entries will be stored in the $_POST array (or $_GET array depending on the form’s method attribute). The values in the left-hand column are taken from the control’s name attribute, and I’ve also marked whether or not the field is a required field for validation purposes.

If the user does not comply with these rules, an error message will be displayed. Any fields already completed will be left unchanged, allowing the user to simply adjust her input and re-submit the form without having to enter all of the data again. See example below.

Let’s look at the PHP required for validating the form. All of this code would be placed towards the top of the page before the HTML for the form:

// define variables and initialize with empty values
$nameErr = $addrErr = $emailErr = $howManyErr = $favFruitErr = "";
$name = $address = $email = $howMany = "";
$favFruit = array();

    if (empty($_POST["name"])) {
        $nameErr = "Missing";
    else {
        $name = $_POST["name"];

    if (empty($_POST["address"])) {
        $addrErr = "Missing";
    else {
        $address = $_POST["address"];

    if (empty($_POST["email"]))  {
        $emailErr = "Missing";
    else {
        $email = $_POST["email"];

    if (!isset($_POST["howMany"])) {
        $howManyErr = "You must select 1 option";
    else {
        $howMany = $_POST["howMany"];

    if (empty($_POST["favFruit"])) {
        $favFruitErr = "You must select 1 or more";
    else {
        $favFruit = $_POST["favFruit"];
// the HTML code starts here

The code starts by creating and initializing the variables used in the validation process:

  • A variable for each of the text fields and the favourite fruit array
  • Error message variables for each field

The exception is the brochure checkbox which does not need to be validated as it is an optional field.

Next determine whether the form has been submitted by checking how the page was requested. If the form has just been requested, then the if statement will be bypassed. The function empty() checks the text fields for name, address, and email, and the array for favorite fruit. isset() checks whether a radio button is set for the fruit count. If any are empty, a suitable error message is assigned to the error variable.

In the example here I am checking the $_POST array because the form’s method is POST. If method was GET, then I would check the $_GET array for the input values.

Having run these checks, the code would continue with the HTML for the page. PHP needs to be incorporated into the HTML for each element:

  1. To print the value submitted in the text fields so the user does not have to retype it. The value will of course be blank if the form has just been loaded and not submitted.
  2. To print any error messages. Again these will be blank if the form has just been loaded or if there is no error for the field.

Here is the HTML definition of one of the input fields:

<input type="text" name="name" value="">

And here is the same code amended to include the first point specified above:

<input type="text" name="name"
 value="<?php echo htmlspecialchars($name);?>">

And then again to address the second point above:

<input type="text" name="name"
 value="<?php echo htmlspecialchars($name);?>">
<span class="error"><?php echo $nameErr;?></span>

htmlspecialchars() is used here for the same reason it was used earlier with PHP_SELF – to protect against XSS attacks.

The use of the class error provides a hook with which you can style the error message using CSS.

.error {
    color: #FF0000;

Extending the Form’s Usability

With a little more effort, you can also remember the choices the user made from the radio buttons and select.

<input type="radio" name="howMany" 
 <?php if (isset($howMany) && $howMany == "zero") echo "checked"; ?>
 value="zero"> 0
<input type="radio" name="howMany"
 <?php if (isset($howMany) && $howMany == "one") echo "checked"; ?>
 value="one"> 1
<input type="radio" name="howMany"
 <?php if (isset($howMany) && $howMany == "two") echo "checked"; ?>
 value="two"> 2
<input type="radio" name="howMany"
 <?php if (isset($howMany) && $howMany == "twoplus") echo "checked"; ?>
 value="twoplus"> More than 2

Code has been added to check whether the variable associated with the radio button has been defined within the validation section. If so, then checked is outputted as part of the element’s HTML.

Now to address the select menu. It is actually a better idea to restructure the code as a loop than to blindly add code to check each option manually. The loop would generate the HTML for the options on the fly, and the check if the option has been selected or not can be incorporated into it.

<select name="favFruit[]" size="4" multiple="">
$options = array("apple", "banana", "plum", "pomegranate", "strawberry", "watermelon");
foreach ($options as $option) {
    echo '<option value="' . $option . '"';
    if (in_array($option, $favFruit)) {
        echo " selected";
    echo ">" . ucfirst($option) . "</option>";

If you are not yet familiar with PHP loops, you may want to read my earlier article, Learning Loops.

Note that the difference here is the use of the attribute selected; radio buttons use checked and select options use selected. It’s just one of those minor inconsistencies we have to live with.

One topic which I have not addressed and is outside the scope of this article is what you would do with the data after validation is successful. There are a number of possibilities, including saving it in a database or emailing the data to yourself. Whichever you choose, you need to be sure:

  • The form has been submitted by the user
  • The data entered by the user is error-free


Validation is essential, particularly if you are going to save the data in a database – remember the old saying, GIGO (Garbage In, Garbage Out), and you won’t go far wrong. In this article you have learned how to create a simple HTML form and validate it with PHP. Along the way a number of techniques have been used to re-display user input and display error messages. For further information on $_SERVER, $_POST, and $_GET, read the article Introducing Superglobals and of course the PHP documentation.

And if you enjoyed reading this post, you’ll love Learnable; the place to learn fresh skills and techniques from the masters. Members get instant access to all of SitePoint’s ebooks and interactive online courses, like Jump Start PHP.

Comments on this article are closed. Have a question about PHP? Why not ask it on our forums?

Image via Valentyn Volkov / Shuttestock

  • Tex Morgan

    Use something like:
    foreach ($_POST as $key => $value) {
    $_POST[$key] = mysql_real_escape_string($value);
    to protect your database from serious injection problems. Or better:
    function protectDB($variable){


    • Tex Morgan

      The function I meant to put:
      function escape_data($connection,$data) {

      if(ini_get(‘magic_quotes_gpc’)) {

      $data = stripslashes($data);


      if (function_exists(‘mysqli_real_escape_string’)) {
      $data = mysqli_real_escape_string( $connection, trim($data));
      else {
      return -1;

      return $data;
      }//end of function

    • Sebastiaan Stok

      You should never ‘just’ convert input to an escaped MySQL string. What if you want to use it in a file? Always only convert at the place you use it!

      • This is a great advice. Too often people use mysql escape functions just because it’s the common usage.

  • I like to use my own personal validation function:
    // validate user input
    // $input: variable to be validated
    // $type: nofilter, alpha, numeric, alnum, email, url, ip
    // $len: maximum length
    // $chars: array of any non alpha-numeric characters to allow
    function validate($input, $type, $len = null, $chars = null) {
    $tmp = str_replace(‘ ‘, ”, $input);
    if(!empty($tmp)) {
    if(isset($len)) {
    if(strlen($input) &gt; $len) {
    return FALSE;
    if(isset($chars)) {
    $input = str_replace($chars, ”, $input);
    $input = str_replace(‘ ‘, ”, $input);

    switch($type) {
    case ‘alpha’:
    if(!ctype_alpha($input)) {
    return FALSE;

    case ‘numeric’:
    if(!ctype_digit($input)) {
    return FALSE;

    case ‘alnum’:
    if(!ctype_alnum($input)) {
    return FALSE;

    case ’email’:
    if(!filter_var($input, FILTER_VALIDATE_EMAIL)) {
    return FALSE;

    case ‘url’:
    if(!filter_var($input, FILTER_VALIDATE_URL)) {
    return FALSE;

    case ‘ip’:
    if(!filter_var($input, FILTER_VALIDATE_IP)) {
    return FALSE;

    case ‘nofilter’:
    return TRUE;
    return TRUE;
    } else {
    return FALSE;

    // example use:
    $phone = isset($_POST[‘phone’]) &amp;&amp; validate($_POST[‘phone’], ‘numeric’, 20, array(‘(‘,’)’,’-‘)) ? $_POST[‘phone’] : null;
    $email_addr = isset($_POST[’email_addr’]) &amp;&amp; validate($_POST[’email_addr’], ’email’, 255) ? $_POST[’email_addr’] : null;
    $msg = isset($_POST[‘msg’]) &amp;&amp; validate($_POST[‘msg’], ‘nofilter’) ? $_POST[‘msg’] : null;

    • Olasunkanmi Ogidan

      Pls, how do I implement your validation function? How can I display error messages? Thanks.

  • Form validation is serious business, and mostly very crucial as its the spot where users can send inaccurate data or hack your site if proper security is not set, @Martins your validation function is really good, Zend and Yii have good Form Validation classes.

  • As the previous poster mentioned, form validation is a complicated and error-prone activity and should be handled by using existing libraries instead. Apart from the already mentioned I’d like to recommend the Symfony2 Validator component.

  • Bob

    Is there any way you can post all the code so I can see this all tied together? I am totally new to this and would like to understand better and seeing the whole thing laid out would be very helpful.

  • I can’t see any reason for action=””>
    This does nothing to filter the form content, as the comment implies, it’s only affect is on the name of the page?

  • Your approach to form validation is very outdated, and I wouldn’t recommend it at all. Your code shows absolutely no re-use at all — no functions or objects. Form validation is something that has been solved by libraries and frameworks thousands of times over, so why re-invent the wheel? Programming should be about minimising the code you write and being able to re-use as much as possible. Take a look at the CodeIgniter form validation system, for example. It’s extremely flexible and comes with many validation rules that have been thoroughly tested, saving you having to roll your own.

    Also, your comment that htmlspecialchars protects you against XSS is untrue. Your example wouldn’t not escape single quotes, for example, which could lead to JavaScript being injected into your page. See this article for more details:

  • I’d like to chime in on the discussion here in my capacity as Managing Editor to raise a few points.

    First, the reactions I have received on this article here is slightly disappointing because I expressly asked Iain to write it. I like to throw in some beginner articles here and there so that there is something for everyone; PHPMaster should be a site not exclusively for “masters,” but also for beginners starting on their journey to “masterhood.” I do think there is merit in a beginner-level article demonstrating $_SERVER[“REQUEST_METHOD”], $_GET/$_POST, etc. As a beginner such things seem difficult or magical, and only as experts do they become boring and common place. We all grow and learn. Certainly a beginner shouldn’t be afraid to try more advanced framework-based options, but under the hood aren’t they just using similar tactics (albeit encapsulated) discussed in this article anyway?

    Second, I want to thank everyone for their polite feedback. The point of growing from this starting point as a beginner and graduating to a framework offering is something that wasn’t conveyed by the article, and I’ll take responsibility for the confusion/omission. Your comments are valued, and I appreciate as well that none of them have been snarky or nasty. Not only have they helped correct my own omission for future readers, but they show the community we’re building here can clarify things, disagree, whatever without the nastiness I’ve seen in other sites. Thank you for that!

    With all that said, there have been some beginners who have asked for a sample of working code. Iain did not provide one, and I didn’t think the article needed it at the time. I have pieced together a sample from this article for those who are interested. I’m a bit hesitant to put it as official repo under PHPMaster’s GitHub account because of the reaction/discussion here, and have instead made it available as a gist.

  • A newbie. To process my form i do this

    if (isset($_POST['submit']))
    //code to process the form goes here


    My question is this.
    1. Using isset function to check the submit button is it not good to check if a form has been submitted?
    2. Setting the action=” does it prevent XSS?

  • To validate the form, i usually create a function with two argument one is current control name and second is check whether it is required or not, and then return true and false and thus process the form.

  • Kikloo

    Isn’t jquery’s validation plugin good enough for validating forms ?? I think its good!

  • I think,using jquery for form validation will be better as it can reduce server load.

    • av

      in this case, i can submit my own form with “submit” referring to your form !!
      you can use jquery, but not instead of

  • Well I appreciate a tutorial like this, as I can test it on the WAMP server, as in yeah I didn’t see a single thanks because people expect someone else to create tutorials when they don’t themselves. So get out there and create a tutorial, and see what responses YOU GET!!!.

  • I usually use JavaScript for form validation but I do some validation at PHP level too.
    When using JavaScript to validate the html form is better because if you do it in PHP and some error occurs, then you need to return all data to user and pre-populate the form again and you have more urls to encode/decode etc.

  • I am totally new to php and was looking hard for form validation and this tutorial looks good. Taking about the security issues, what are the main ways to hack a site? All I know about is SQL injection and XSS. Is there a method which I can apply to prevent both XSS and SQL injection at once?

  • Rizbi

    Tried what I learnt here. Problem is when I submit an empty form, it sends me to a blank page. obviously I want the same form with the error messages printed next to it. Please help!

  • You cannot rely on jquery validation 100% since the user can turn java off in the browser. You still need php validation.

    • elijah

      Kelvin is right. Validating a form with just javascript is very easily to work around. All someone would have to do is turn their java or javascript off and your form validation would be shut off and someone could put whatever they want into it. This is very bad if you use that type of validation for something like a user registration form, or when putting unique information into a db

  • I don’t agree with you when you say almost every form must use POST.

    POST requests are never cached, whereas GET are. In addition, refreshing a POST requires explicit confirmation by the user.
    That being said, POST should be used whenever the form submission implies *data alteration* on the server side (You don’t wanna bypass processing an online order because of caching! And showing a popup window on refresh is a good idea).
    GET should be used otherwise, for performance reasons.
    Example: newsletter subscription form = POST ; search form = GET.

    Visibility is not a concern since both POST and GET (and even COOKIE) are editable by clients. The “never trust user input” motto states there MUST be server-side validation whichever method you choose. So, who cares whether data is visible in the URL or not?

    • samimi_it

      @ Léo LETARO: “So, who cares whether data is visible in the URL or not?”
      ha? really!

  • This tutorial might be confusing for beginners

    Hi there,
    I had a look at this tutorial and found it good but misleading too. I guess that beginners willing to do some PHP form validation might just cut and past the code tweaking it a little bit and use it for their own needs. Fair enough. But the thing is that if they do, they might have a bit of a surprise. When one uses
    [code] $_SERVER[&quot;REQUEST_METHOD&quot;]==POST [/code]
    along with
    [code] $_SERVER[&quot;PHP_SELF&quot;] [/code]
    sprinkle some
    [code] header(&quot;Location: the_next_page.html&quot;) [/code]
    on the top of that in order to access THE PAGE after data have been thoroughly validated…. and a beginner might just be surprised as to where his validated fields have gone. ;)

    • GEM

      I wanted to post the validated form to DB by calling a dbpost.php file under form action. How to combine this with “htmlspecialchars($_SERVER[“PHP_SELF”]“.

  • ubaidrehman

    Thanks alot really help me dude !

  • hi,
    please help me!
    I need to put filter validate of email and phone number, because sometimes I getting submit form, where users put wrong email or phone number just like 123456789, please help me to improve my form.
    i would really appreciate it.
    Thank You!

    • neel

      more clarification required for phone no . if you need email validation let me know

  • Guy

    How do I insert this data into the database

  • @Guy, To Insert your data in databse.You must establish a connection to your database.Assume of using mysql
    then code is
    then use of mysql_query to insert values in db
    $mysql_query(“SQL query”,$con);
    Tip: You must create a table to insert info on db.Before inserting create a correct table.
    Thanks hope you will understand.if not try googling

  • ep

    One of the most concise, understandable, and useful explanations of any code that I have ever read. Even though it is only meant to be a starting point, everyone can find the succinct summarization of a complex subject useful. Thanks!

  • please can some one show me how to check input string characters in a form and also how to email the variables to my email address

  • i have been working on it for sometime now and i have not been able to get a better result.I believe in you guys please someone should help me

  • You can also use
    "http://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'] .'" to get url inputed into form.

  • Its Really a nice post I always use js validation.. Now start using PHP validation..Thanks a lot

  • This tutorial is really helpfull for me. I got what I want exactly after googling. But here I’m not clear about what next if form fields are correct. How to response? I want to give response as form is submitted successfully. But, where I can manage this code. Plz rply…

  • Aby

    Oh… I get it… Thanks
    -Aby from GPR

  • Mubashir Ahmad

    O its fine article. Good….

  • Vishal Parkash

    i used the above given code, and it helped me a lot to understand my query, but my issue is that even i am displaying the errors, data is getting inserted into the database. how can i stop this without javascript…?? Is it possible??
    vishal parkash

  • i added the validate as well but it did not work. What sproblem here?
    if (empty($_POST[‘username’]))
    else {
    if (!filter_var($_POST[‘username’],FILTER_VALIDATE_STR))
    $nameErr=”The text is not a name”;
    else {

  • Sam

    What next? How do we get to a piece of code when there are no errors?
    $nameErr = "";
    $name = "";
    if ($_SERVER["REQUEST_METHOD"] == "POST") {
    if (empty($_POST["name"])) {
    $nameErr = "Missing";
    else {
    $name = $_POST["name"];
    Perform Forms actual fuction;
    else {
    Validate again
    A bit more light on this would be helpful

  • Sam

    Ooops! Never saw the gist link, mybad

  • Stephen

    This tutorial was very helpful to me since I am new to PHP. Thank you very much. My one question is when using a non-multiple select field would the validation be the same?

  • Abhinav

    Hey sorry its a little dumb question but how do we check for checked input tags , I mean if set up a checkbox and we need to know if its checked or not using PHP . Thanks in advance

  • Bill

    This is a great beginner article. I’ve been learning PHP for about 6 months and find these really helpful. They’re not bulletproof and frameworks definitely have their usage, but those of us just learning don’t understand all that complex jargon and need something simple to relate to and implement now. As readers of the internet, it’s our job to make sure to cover the security issues that this article doesn’t cover.

  • Matthew

    This tutorial will only work on that same page. what if the processing page is another URL used for inserting data into the database e.g

    How do one go about it

  • MD

    I am a beginner and read what Timothy Boronczyk had written on March 15, 2012 at 6:22 pm saying ” have instead made it available as a gist” . I went to the web site and copied the raw code and it didn’t seem to work and I am even more confused now than when I started.

Get the latest in PHP, once a week, for free.