A Single Article

Read it, comment, and share it with your friends

Easy form processing with PHP

Posted October 23 in Technology.

I was working on a simple contact form processing script yesterday and I needed it to be really flexible, because this one script was being used to handle 8 different forms in 8 different places. AJAX was being used to prevent spam and return the response, so I didn’t need to deal with any redirects, but I still had to handle different inputs depending on which form was submitted. With inputs, as always, there is the problem of sanitizing data.

A very procedural approach would involve something like the following:

1
2
3
4
5
6
7
8
if( isset( $_POST['name'] ) )
{
  $name = htmlspecialchars( stripslashes ( $_POST['name'] ) );
}
else
{
  // error, blah blah blah
}

Of course, if I decide to change the way I clean data later on, I would have to change this for every single input. So normally I would write a custom function:

1
2
3
4
5
6
7
8
9
function sanitize($s) 
{
  return htmlspecialchars( stripslashes ( $s ) );
}
 
if( isset( $_POST['name'] ) )
{
  $name = sanitize ( $_POST['name'] );
}

This is allright, but there are a lot of things lacking:

  • I still have to do isset( $_POST[ ... ] ) all the time, which is a lot of stuff to type. I don’t even want to have to check if something is set all the time, I just want to process it and check it later when I am done accepting inputs.
  • I don’t have anything yet for handling required/optional inputs and returning errors if something required is not entered.
  • Checkboxes don’t submit anything, they are just set or not set. In their case, I just want to know what was set. My current function is useless for them.

So I thought about how to really make a simple, flexible way to handle all kinds of form input. I decided a couple things:

  • There are two kinds of form inputs: optional ones, and required ones. I should have an easy way to check that all required inputs were filled. So, I could have an array for all the optional inputs, and another for all the required inputs. After I accept all the inputs, I could just run through the second array and make sure everything has a value. If anything doesn’t, that’s an error.
  • There are two kinds of responses: either a list of errors, or a message saying that everything went fine. Since I mentioned that I will build an array of errors, I will then check that the array is empty. If it is, that’s success, and if it’s not, then I print out all the errors.
  • Every form input except for checkboxes returns a value. For checkboxes, I should just check whether they were set or not. So I need a separate function to accept checkboxes, but this is fine since they are optional anyway. I could use an extra array to hold them too.

With these ideas in mind, I wrote this code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/* Four arrays to store data */
$optional = array();
$required = array();
$checked = array();
$errors = array();
 
/* Sanitize POST input */
function sanitize($s)
{
  /* Notice $s is the name of the input,
    not the value itself */
  if( isset( $_POST[$s] ) )
  {
    /* Could do any number of functions here */
    return stripslashes( $_POST[$s] );
  }
  else
  {
    /* Empty string, also defined as NULL */
    return '';
  }
}
 
/* Check if a checkbox was set */
function check($c)
{
  if( isset( $_POST[$c] ) )
  {
    /* Notice I don't want a value, I just 
      want to keep the name */
    return $c;
  }
  else
  {
    return '';
  }
}
 
/* Ready to handle a form (simple example here) */
$required['name'] = sanitize('name');
$required['email'] = sanitize('email');
$optional['location'] = sanitize('location');
$optional['website'] = sanitize('website');
$checked['subscribe'] = check('subscribe');
 
/* Now check all required inputs */
foreach($required as $key => $value)
{
  /* '' means empty input */
  if( '' == $value )
  {
    /* Just a list of what's missing */
    $errors[] = $key;
  }
}
 
if( count($errors) > 0 )
{
  // we have errors, handle that
}
else
{
  // success! send e-mail, insert to DB, etc.
}

Notice something about this code:

  • The check for set and data sanitization is all wrapped in the sanitize function.
  • I only have to check for missing required stuff once at the end.
  • The functions are longer than the example processing itself, but these functions could be reused for any form processing on just about any form.

See, it’s really simple to use and I never have to type another $_POST[]. Plus, I could also add data validation to this without much trouble. I could give sanitize one more parameter to define some possible validation routines. Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* $v is validation routine
  empty means no validation (default) */
function sanitize($s, $v = '')
{
  if( isset( $_POST[$s] ) )
  {
    switch($v)
    {
      case 'email':
        // check if it's a real email
      break;
      default:
        return stripslashes( $_POST[$s] );
      break;
    }
  }
  else
  {
    return '';
  }
}

Anyway, you get the point; this is a really simple, clean, and reusable way of handling form input. It’s great if you want to write one script that can handle multiple forms, or even if you want a way of accepting input apart from any other processing you might do afterward. If it looks useful to you, you can use the ideas I mentioned here. And if I made a mistake, let me know. I haven’t had the chance to test this code.


Get a Trackback link

2 Trackbacks/Pingbacks

Other blogs referencing this article
  1. Pingback: Syntax Higlighted | The Montoya Herald on October 26, 2007
  2. Pingback: PHP techniques I use all the time | The Montoya Herald on November 10, 2007

6 Comments

Responses to my article
  1. Jem October 24, 2007

    I’ve not tried this myself (I’ve only just thought of it), but surely it would just be easier/more compact to build the arrays into the actual form elements.. e.g. input name="required[name]"

    ..and then just loop through the required array and check for empties?

    foreach ($_POST['required'] as $key => $value) {
    if (empty($value))
    // do your error handling here
    }

    You can then deal with any non required elements and sanitisation afterwards. That seems more efficient than having all those arrays etc. Would need to test it to be sure, of course.

    (I’ve no idea how well the code in this will come out, I can’t remember what WordPress strips!)

  2. Christian Montoya October 24, 2007

    Jem, I’ve never known that you can put an array right into a form element. Are you sure about this? Seems like I would have seen it before if it were possible.

    Also, in some cases you aren’t the one who wrote the original form and you can’t change it, or at least you can’t rely on every form to have “required[name]” and “optional[name]” in an environment where a lot of people are involved and not every page is yours, so I’d say the code I showed is a bit more flexible for that.

  3. Jem October 25, 2007

    I’m surprised you’ve not come across using arrays in the HTML forms before - it’s how you gather data from things like multiple-option checkboxes and radio buttons effectively. I’m sure there are lots of resources on it but this was the first I found in google: http://tinyurl.com/2seqt6

    Obviously if you can’t change the form it’s not going to work, but otherwise I see no reason why it wouldn’t :)

  4. Christian Montoya October 25, 2007

    Oh wow Jem, I had NEVER heard of that before. That’s great stuff. Like I said, it’s not too useful for my current situation when I’m dealing with a lot of forms in a lot of places and I can’t necessarily change the markup, but I will definitely use that in situations where I have complete control.

  5. Kylee November 11, 2007

    Jem, yes but that would be easy to bypass for someone wanting to cause havok.

    name=”required[name]”

    could be erased using a simple firefox extension that allows me real time editting of the html. It’s easier to declare required fields on the backend, where users can’t edit them.

  6. benji November 12, 2007

    Kylee, I think that could lead to security issues for the site. It could be used to overwrite another Array just by rewriting the HTML form, don’t you think?

    ps. great article!

Leave a comment

Share your thoughts with the world

You can use Markdown, or you can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>

Please keep comments respectful and on topic.

This form is guarded by Akismet, so don't waste your time trying to submit spam. It won't work. Ever.





Stay on top of new updates at this site: Subscribe to the Feed!