3
\$\begingroup\$

I have multiple form validation checks around my site so I decided to write them as functions to simplify the process of creating the validation pages, here is a snippet for an understanding of what I'm doing.

// Declare regex variables

   $regex_email = "/^[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+\.[a-zA-Z.]{2,5}$/";
   $regex_password = "/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*\W).*$/";

// Declare validation functions

    function checkEmail($regex, $email) {

        if (!preg_match($regex, $email)) {

            $error = "The format of that Email Address is invalid";
            $solution = "Please go back and <a href=\"javascript:history.go(-1)\">try again</a>";

        }

        return array($error, $solution);

    }

    function checkPassword($regex, $password) {

        if (!preg_match($regex, $password)) {

            $error = "Your Passwords does not meet our requirements";
            $solution = "Please go back and <a href=\"javascript:history.go(-1)\">try again</a>";

        }

        return array($error, $solution);

    }

I was hoping that when I come to validate it I could simply use:

// Values for $email and $password are fetched from `$_POST` before hand...

// Validate form

    list ($error, $solution) = checkEmail($regex_email, $email);
    list ($error, $solution) = checkPassword($regex_password, $password);

// Display error

    echo("Error:<br />".$error."<br />Solution:<br />".$solution."");

But alas, it doesn't work and no errors at all are displayed and I'm having to do error checks after each one like this:

// Validate form

    list ($error, $solution) = checkEmail($regex_email, $email);

    if (!$error) {

        list ($error, $solution) = checkPassword($regex_password, $password);

    }

// Display error

    echo("Error:<br />".$error."<br />Solution:<br />".$solution."");

I don't mind doing it like this, but when I have say 10+ check*VALUE* functions being called, each one wrapped in an if statement within an if statement and so on, it looks a little messy, I wasn't sure if there was a different approach which would work more like the first way I tried without all the if statement's.

\$\endgroup\$
  • \$\begingroup\$ Javascript in your backlinks. Just give them a class and hook the javascript into that class, so that if you ever want to change the behavior, you can change it in the js instead of everywhere in the php code. \$\endgroup\$ – Kzqai Nov 13 '11 at 18:32
1
\$\begingroup\$

I'd do the following:

function checkEmail($errors, $email) {
    $regex_email = "/^[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+\.[a-zA-Z.]{2,5}$/";
    if (!preg_match($regex_email, $email)) {
        array_push($errors, "The format of that Email Address is invalid");
        array_push($solutions, "Please go back and <a ...>try again</a>");
    }
    return array($errors, $solution);
}

$errors = array();
$solutions = array();
list ($errors, $solutions) = checkEmail($errors, $solutions, $email);
// ...

if (count($errors) > 0) {
    // TODO: print the errors
}

Consider declaring the $regex_mail variable inside the checkEmail function.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I'm not at my computer with all my files to test this out, but from reading it, would that list ALL the errors or just the first one it detects? I was hoping to just display the first error it says, rather than a big list, but I'm sure I can figure that out with something. Thanks for the heads up on the position of the regex variables declarations too! If I get it working I'll be back to mark it as top answer. \$\endgroup\$ – no. Nov 7 '11 at 10:52
3
\$\begingroup\$

This might not be what you are looking for but I recently wrote this code to validate my forms.

As you might notice I define the data to be validated in the $validate array. Then some loops run through them and show the proper errors. If no errors are found, it sends the form.

With some modifications, you could probably use something similar. Hope it helps.

<?php

    # post data collection
    $name   = "Full name";
    $email  = "a@b.c";
    $age    = "193";
    $x      = "s";
    $y      = "s";

    # select data that needs validation
    $validate   = array(
        'required'      => array($name, $email, $x, $y),
        'validEmail'    => array($email),
        'validNumber'   => array($age),
        'validAlpha'    => array($name)
    );

    # error messages
    $errorsMsgs = array(
        'required'      => 'Please fill out all required fields.',
        'validEmail'    => 'is an invalid email address.',
        'validNumber'   => 'is an invalid number.',
        'validAlpha'    => 'contains invalid characters. This field only accepts letters and spaces.'
    );

    $errorMarkup    = "<h1>We found a few errors :-(</h1><h2>Please fix these errors and try again</h2><ol>";
    $successMarkup  = "<h1>Success!</h1><h2>Your form was sent successfully.</h2>";
    $backMarkup     = "<a href=\"" . $_SERVER['HTTP_REFERER'] . "\">Back to form</a>";

    # begin state
    $valid = true;

    # loop through fields of error types
    foreach ($validate as $type => $fields) {
        # loop through values of fields to be tested
        foreach ($fields as $value) {
            # throw error if value is required and not entered
            if ($type === 'required' && strlen($value) === 0) {
                $errorMarkup .= "<li>$errorsMsgs[$type]</li>";
                $valid = false;
                break;
            }
            else if (
                        $type === 'validEmail'  && !filter_var($value, FILTER_VALIDATE_EMAIL) ||
                        $type === 'validNumber' && !preg_match('/^[0-9 ]+$/', $value) ||
                        $type === 'validAlpha'  && !preg_match('/^[a-zA-Z ]+$/', $value)
                    ) {
                if (strlen($value) === 0) {break;} # skip check if value is not entered
                $errorMarkup .= "<li>\"$value\" $errorsMsgs[$type]</li>";
                $valid = false;
                continue;
            }
        }
    }

    if ($valid) {
        # email form
        $body = $successMarkup . $backMarkup;
        $title = "Form sent";
    } else {
        $body = $errorMarkup . "</ol>" . $backMarkup;
        $title = "Form errors";
    }

    # write html ouput
    echo "<!DOCTYPE html><head><title>$title</title><style type=\"text/css\">body{margin:100px;font:16px/1.5 sans-serif;color:#111}h1{font-size:32px;margin:0;font-weight:bold}h2{font-size:18px;margin:0 0 20px 0}ol,li{list-style-position:inside;padding-left:0;margin-left:0}</style></head><body>$body</body></html>";
?>
| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Thank you for the example kht! I was hoping to stick to the approach I've taken since it works well with everything I've got so far. But it's good to have a working alternative! +1 \$\endgroup\$ – no. Nov 6 '11 at 17:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.