Page 1 of 1

Basic Form Validation Rate Topic: -----

#1 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2889
  • View blog
  • Posts: 10,000
  • Joined: 08-August 08

Posted 29 March 2014 - 11:23 AM

I've seen a lot of beginners write code like that below when attempting to validate forms. While it works, it's not very good. In fact, it's awful. The reasons are that it's long and difficult to read, hard to edit/add to, and can't be reused for another form.
$errors = false;
if(empty($_POST['Firstname']) || strlen($_POST['Firstname']) < 5) {
	echo 'Missing first name.<br>';
	$errors = true;
}
if(empty($_POST['Lastname']) || strlen($_POST['Lastname']) < 5) {
	echo 'Missing last name.<br>';
	$errors = true;
}
if(empty($_POST['Street']) || strlen($_POST['Street']) < 5) {
	echo 'Missing street.<br>';
	$errors = true;
}
if(empty($_POST['City']) || strlen($_POST['City']) < 5) {
	echo 'Missing city.<br>';
	$errors = true;
}
if(empty($_POST['State']) || strlen($_POST['State']) < 2) {
	echo 'Missing state.<br>';
	$errors = true;
}
if(empty($_POST['Zip']) || strlen($_POST['Zip']) < 5) {
	echo 'Missing zip.<br>';
	$errors = true;
}
if($errors) {
	exit;
}



Compare the above to this code:
function report_problems(&$submitted, &$expected, $minimum_length, &$err)
{
//$submitted = Either the POST or GET array can be passed.
//$expected = The names of all elements we expect to be submitted.
//$minimum_length = The smallest number of characters allowed.
//$err = An array of error messages corresponding to the expected submissions.
	$problems = array(); // Initialize to an array holding no problems.
	for($i = 0; $i < count($expected); $i++) { // Iterate through all expected keys.
		$key = $expected[$i];
		if(empty($submitted[$key]) || strlen($submitted[$key]) < $minimum_length[$i]) {
			// If the submitted key is empty or the length is below the minimum set for it, add a warning to the problems array.
			$problems[] = $err[$i];
		}
	}
	return $problems;
}

$expect = array('Firstname', 'Lastname', 'Street', 'City', 'State','Zip');
$min_len = array(5,5,5,5,2,5);
$error_messages = array('Missing first name.', 'Missing last name.', 'Missing street.', 'Missing city.', 'Missing state.', 'Missing zip.');

$form_issues = report_problems($_POST, $expect, $min_len, $error_messages);

if(count($form_issues) > 0) {
	foreach($form_issues as $an_issue) {
		echo $an_issue."<br>";
	}
	exit;
}


Some of the advantages of this code:
  • It's shorter.
  • Adding, removing, or editing elements is just a matter of editing the arrays.
  • The function can be used for multiple forms. You only need to decide what form to process and pass the appropriate information to the function.

Validation can get complicated. I haven't touched on validating dates, times, phone numbers, monetary values, etc. That's why it's so important to keep things simple and readable from the start.

Is This A Good Question/Topic? 2
  • +

Replies To: Basic Form Validation

#2 CasiOo  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1369
  • View blog
  • Posts: 3,019
  • Joined: 05-April 11

Posted 29 March 2014 - 01:49 PM

Oh parallel arrays..
All your fields are now tightly coupled up to the validation logic of report_problems
And I don't really like the method name report_problems ^^

I would much rather have a method which validates just one at a time
Or some kind of chain
//The chain calls the validators in sequence until an invalid result is encountered
$firstnameValidation = new ValidationChain($_POST['Firstname'])
	.validate(ValidateExists)
	.validate(ValidateMinLength);


Implementing such a chain would of course require more code to be written
My PHP skills are still very basic, and I'm not aware of all the possibilities yet ^^
Was This Post Helpful? 1
  • +
  • -

#3 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2889
  • View blog
  • Posts: 10,000
  • Joined: 08-August 08

Posted 29 March 2014 - 02:01 PM

Yes, I started doing it as a class, but that seemed like too big a jump from the first set of code so people who need it might ignore the solution. You'd still have to initialize an array of classes, for example.
Was This Post Helpful? 0
  • +
  • -

#4 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2889
  • View blog
  • Posts: 10,000
  • Joined: 08-August 08

Posted 29 March 2014 - 02:42 PM

Ok, here it is as a class:
class validator {
	protected $expect;
	protected $min_len;
	protected $error_message;
	
	function __construct($val)
	{
		$temp = explode(",",$val);
		$this->expect = $temp[0];
		$this->min_len = (int)$temp[1];
		$this->error_message = $temp[2];
	}

	function report_problem()
	{
		$problems = "";
		if(empty($this->expect) || strlen($this->expect) < $this->min_len) {
				$problems = $this->error_message."<br>";
		}
		return $problems;
	}
}

$validate ="Firstname,5,Missing first name.|Lastname,5,Missing last name.|Street,5,Missing street.|City,5,Missing city.|State,2,Missing state.|Zip,5,Missing zip.";
$valid = explode("|",$validate);
$required_fields = array();
$message = "";
foreach($valid as $needed_field) {
	$required_field = new validator($needed_field);
	$message .= $required_field->report_problem();
}
if($message != "") {
	echo $message;
	exit;
}



Now all you need to do is edit the $validate string.
Was This Post Helpful? 1
  • +
  • -

#5 fredlawl  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 15-April 14

Posted 15 April 2014 - 08:00 PM

View PostCasiOo, on 29 March 2014 - 01:49 PM, said:

Oh parallel arrays..
All your fields are now tightly coupled up to the validation logic of report_problems
And I don't really like the method name report_problems ^^/>/>

I would much rather have a method which validates just one at a time
Or some kind of chain
//The chain calls the validators in sequence until an invalid result is encountered
$firstnameValidation = new ValidationChain($_POST['Firstname'])
	.validate(ValidateExists)
	.validate(ValidateMinLength);


Implementing such a chain would of course require more code to be written
My PHP skills are still very basic, and I'm not aware of all the possibilities yet ^^/>/>


Going off that, I'm a fan of creating user defined functions. This way you can put in and take out exactly what you need in a systematic and custom way. Example implementation:

<form name="form" method="post" action="./">
    <label>First Name:
        <input type="text" name="first_name" value="Foo" />
    </label>

    <label>Last Name:
        <input type="text" name="last_name" value="Foo" />
    </label>

    <label>Last Name:
        <select name="state">
            ...
            <option value="TN" selected="selected"></option>
            ...
        </select>
    </label>

</form>

<?php
    
    ...

    $errors = array();
    foreach ($_POST as $field => $value) {
        $func = 'validate_' . $name;
        if (function_exists($func)) {
            $return = call_user_func_array($func, array($value));
            if ($return !== true) {
                $errors[] = $return;
            }
        }
    }

    function validate_first_name ($value) {
        if (!empty($value))
            return true; // validated!

        return 'Your field did not validate'; // Did not validate -- return msg
    }

    function validate_last_name ($value) {
        if (!empty($value))
            return true; // validated!

        return 'Your field did not validate'; // Did not validate -- return msg
    }


    ...
?>


Was This Post Helpful? 0
  • +
  • -

#6 Chathula  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 8
  • Joined: 22-April 14

Posted 23 April 2014 - 12:09 AM

Nice Tutorial! this is very useful thing for everyone. thanks for this.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1