More efficient PHP form validator?

phpmain2

New Member
Messages
9
Reaction score
0
Points
0
Hi,

I am trying to make a more efficient form validator - I no longer want to use the IF...ELSE... to check whether or not fields are correctly filled out. I am currently programming in PHP and thus would really appreciate any suggestions in PHP (JavaScript is alright, I guess - I try not to use a lot of it, though).

Any free and customizable form validator suggestions? :D
 

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
Server-side, you could use one of the filter functions. filter_var_array can filter a whole array of data in one call.

Alternatively, hold verification information (REs, functions) in an ancillary data structure. Loop over the input array, applying the verification info for each input field. This amounts to rolling your own filter_var_array.
PHP:
define('VRFY_RE', 1);
define('VRFY_FUNC', 2);
...

function verify($specs, $dfltSpec = null) {
    $fail = array();
    foreach ($_REQUEST as $name => $val) {
        if (isset($specs[$name])) {
            $spec = $specs[$name];
        } elseif (is_null($dfltSpec)) {
            continue;
        } else {
            $spec = $dfltSpec;
        }
        switch ($spec['type']) {
        case VRFY_RE:
            if (! preg_match($spec['pattern'], $val)) {
                $fail[] = array('name' => $name,
                                'value' => $val,
                                'msg' => isset($spec['errmsg']) 
                                         ? $spec['errmsg']
                                         : 'Failed to match RE');
            }
            break;
        case VRFY_FUNC:
            if (isset($spec['args'])) {
                $args = $spec['args']
            } else {
                $args = array();
            }
            array_unshift($args, $val);
            if (! call_user_func_array($spec['func'], $args)) {
                $fail[] = array('name' => $name, 'value' => $val, 
                                'msg' => isset($spec['errmsg']) 
                                         ? $spec['errmsg'] 
                                         : "Failed to satisfy function '{$spec['func']}'.");
            }
            break;
            ...
        default:
            throw new InvalidArgumentException("{$spec['type']} is not a valid verification type (trying to verify input '$name').");
        }
    }
    return $fail;
}

function validUSPhoneNum($candidate) {
    $candidate = preg_replace('/\D+/', '', $candidate);
    return preg_match('/(1\d{3})?\d{7}/', $candidate);
}
function validUKPhoneNum($candidate) {
    $candidate = preg_replace('/\D+/g', '', $candidate);
    return preg_match('/(\+44|0)([1-358-9]\d|60|7[05-9])\d{7,8}/', $candidate);
}
$specs = array(
    'zip' => array('type' => VRFY_RE, 'pattern' => '/^\d{5}(?:-\d{4})?/'),
    'phone' => array('type' => VRFY_FUNC, 'func' => 'validUSPhoneNum'),
    ...
);
try {
    $verifyErrors = verify($specs);
} catch (InvalidArgumentException $iae) {
    error_log($iae);
    echo "An internal error occurred. Sorry about that; it's been logged, and we'll look into it.";
}

As far as JS goes, it's good to verify client-side in addition to server side for usability's sake so the user doesn't have to wait for a message round-trip to learn something's wrong with the form. (JS is also a nicer language that PHP.) There are plenty of articles about this online:

Just be sure you notify the user of invalid elements by marking them and displaying messages in the page, rather than using an alert. Some of the articles you'll find will make this point, but I want to stress it here. An easy way of marking invalid elements is to add an "invalid" class, which is styled to have (e.g.) a red border. Add a 'blur' event listener to each element so the user doesn't have to submit the form. You can also use input filters to prevent users from typing invalid characters. Alternatively, there are plenty of modules for JS libraries that can validate forms. For examples, see jQuery's Plugins/Validation and Prototoype's JSValidate. Google searches will turn up more.

See also:
 
Last edited:
Top