07 Oct 2007

PHP Form validation and processing – part 2

Filed under: Development | Taged as: , | 0 comments

Part 1 about PHP form validation and processing showed how good forms are structured and how to validate input fields. Part two handles drop-down menus, checkboxes and radio buttons, inline error messages.

Drop-down menus, checkboxes and radio buttons

For all three widgets, you have to make sure, that the value supplied is one of the allowed choices. Otherwise another value in the right form (number, string) can be injected. To achieve this, use an array to generate the menu or boxes. Then validate the input by checking that value is in the array. in_array() and array_key_exists() are the build-in functions to do the validation. Here’s an example for a drop-down menu.

<?php
// generate menu
$choices = array('Monday', 'Tuesday', 'Wednesday', 'Thursday');
print "<select name='day'>n";
foreach($choices as $key=>$choice){
    print "<option value='{$key}'>{$choice}</option>n";
}
print "</select>n";

// validate selection later
if(!array_key_exists($_POST['day'], $choices)){
    print "You must select a valid day!";
}
?>

Checkboxes and radio buttons work in the same manner. For a group of checkboxes use array_intersect() to ensure that the set of submitted values is contained within the set of acceptable values.

Email addresses, dates, credit card numbers

Email addresses require some special handling for validation according to the RFC 2822 rule. You can download a handsome function by Carl Henderson to do the job for you.

Validation of dates and times effords speperating all single elements (day, month, year, hour, etc.) and check every item for its plusibility.

Credit card numbers use the Luhn algorithm to prevent against errors. this algorithm manipulates the individual digits of a number to validate if it is acceptable or not. Like validation email addresses, this requires a syntactic validation to make sure the number matches the standard.

Inline error messages

Good forms provide good feedback. When ther’s a problem with the data entered you should print out error messages alongside the widgets. You also should preserve the values the user already entered. You can keep track of errors while validating the input data. A good method is storing the messages in an array keyed by element name and print it next to each name. To preserve the entered and selected data use another array and store the requred HTML idioms: the encoded value for inputs, selected for drop-downs and checked for radio buttons and checkboxes

Basically, this takes three steps: First, validate the form and store the error messages. Second, preserve the entered values. Finally, display the form with error messages and values. The following simple example focuses on this steps and takes up some of the issues discussed earlier.

<?php
// options for drop-down menu
$choices = array('Select day', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday');

if($_SERVER['REQUEST_METHOD'] == 'GET'){
    // display form when GET
    showForm(array());
}
else{
    // process form if POST
    $errors = validateForm();
    if(count($errors)) showForm($errors); // if errors show again
    else print 'Form submitted succesfully!'; // no errors
}

// function generating form
function showForm($errors){

    global $choices;

    // set defaults
    $defaults = array();
    $defaults['comment'] = isset($_POST['comment']) ? htmlentities($_POST['comment']) : '';
    foreach($choices as $key => $choice){
        if(isset($_POST['day']) && ($_POST['day'] == $key)) $defaults['day'][$key] = 'selected';
        else $defaults['day'][$choice] = '';
    }

    // print form
    print "<form action='{$_SERVER['SCRIPT_NAME']}' method='post'>n";

    print "<div>n";
    print "<label>Select day</label>";
    print "<select name='day'>n";
    foreach($choices as $key => $choice){
        print "<option value='{$key}' {$defaults['day'][$key]}>{$choice}</option>n";
    }
    print "</select>n";
    showError('day', $errors);
    print "</div>n";
   
    print "<div>n";
    print "<label>Your comment</label>";
    print "<input type='text' name='comment' value='{$defaults['comment']}'/>n";
    showError('comment', $errors);
    print "</div>n";
   
    print "<input type='submit'/>n";

    print "</form>n";

}

// display error
function showError($type, $errors){
    if(isset($errors[$type])) print "<b>{$errors[$type]}</b>n";
}

// validate data
function validateForm(){

    global $choices;
   
    // start validation and store errors
    $error = array();
   
    // validate comment input
    if(!(isset($_POST['comment']) && (strlen($_POST['comment']) > 5)))
            $errors['comment'] = 'Insert a comment of at least 5 characters';

    // validate drop-down
    if(!(isset($_POST['day']) && (array_key_exists($_POST['day'], $choices)) && $_POST['day'] != 0)) $errors['day'] = 'Select a day';

    return $errors;

}
?>

The last part covers the following topics: prevent multiple form submissions, escaping data, securing forms and prevent hacks.

Related posts

Share and Enjoy:

  • RSS
  • Digg
  • del.icio.us
  • Google Bookmarks
  • FriendFeed
  • MisterWong
  • StumbleUpon
  • Technorati
  • Twitter
  • NewsVine

Leave a Reply