The Montoya Herald, a weblog about Blueprint, jQuery, design, music and life, publishing on the web since September 2005. Written by Christian Montoya: developer, designer and entrepreneur.

The Montoya Herald — ChristianMontoya.com

Search

I Recommend

Genesis Rocket

Like What I Do?

My Amazon.com Wish List

On this domain

Elsewhere

Easy form processing with PHP

Posted on October 23, 2007.

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:

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

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:

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

  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

  1. Jem on 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 on 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 on 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 on 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 on 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 on 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

Use Markdown or basic HTML. For posting code, use Postable. Please keep comments respectful and on topic.