Page 1 of 2

Form Validation Class

Posted: Tue Mar 30, 2004 5:26 pm
by lazy_yogi
Rather than re-invent the wheel, I was wondering if anyone already has a form validation class that they're pretty happy with and wouldn't mind if I could get a hold of.

I'm hoping for something as generic as possible.

Thanks for any help,
Eli

Posted: Tue Mar 30, 2004 5:35 pm
by kettle_drum
What sort of validation do you want doing? Presence check? Range check? xss check? error check? content checks?

Posted: Tue Mar 30, 2004 6:29 pm
by McGruff
I could post something - but it would be a long post with several classes which work together. It works but is also a work in progress if you see what I mean. As such, it's not properly documented at the moment and you'd be on your own as to figuring it out.

If this looks interesting, I'll dig it out:

Code: Select all

<?php
// $form_meta is a meta data array describing each form field & tests to be carried out on it
$this->firewall =& new Firewall($_POST, $form_meta);

// alien keys check
if(isset($this->firewall->getError('match_keys')))
{
    // forged form
    return;
}
if($this->firewall->redisplay())
{
    // redisplay the form
    // error messages are provided by Firewall
    return;
}
// $_POST keys are always accessed via Firewall, eg:
$title = $this->firewall->getVar('title');

// or escaped var for use in a db query:
$title = $this->firewall->getEsc('title');

?>

Posted: Tue Mar 30, 2004 8:00 pm
by Sevengraff
I use something pretty simple in my blogger project. It's based off what Nay posted here: viewtopic.php?t=16077

Posted: Wed Mar 31, 2004 7:06 am
by lazy_yogi
kettle_drum wrote:What sort of validation do you want doing? Presence check? Range check? xss check? error check? content checks?
Well ideally it would be completely generic so I don't have to write any more validation code.

something like a function like so

validate(arg, string argName, int minLen, int maxLen, bool allowEmpty,
bool allowAlpha, bool allowDigits, string specialChars, string errCode)
{

}

arg is the argument
argName is the name for in the error message
minLen, maxLen are self-explainitary
allowEmpty, allowAlpha, allowDigits also self explanitary
special chars are chars which are allowed, so might be "-_'!"

thats alot of params tho, and looks quite ugly for an interface.
But the only other way is to set it in objects and so will take more lines, which I would prefer not to do - cuz validation of 20 fields wil then take 80 lines instead of 20

Eli

Posted: Wed Mar 31, 2004 8:07 am
by CoderGoblin
Rather than use (arg, string argName, int minLen, int maxLen, bool allowEmpty,
bool allowAlpha, bool allowDigits, string specialChars, string errCode)

You could look at func_num_args() and func_get_arg() within the function to process any number of arguments based on a set of defined keywords.

OR

Pass in array with specific keys and use isset($args['key']) to check.

Just a couple of ideas.

Posted: Wed Mar 31, 2004 9:30 am
by McGruff
lazy_yogi wrote:thats alot of params tho, and looks quite ugly for an interface.
But the only other way is to set it in objects and so will take more lines, which I would prefer not to do - cuz validation of 20 fields will then take 80 lines instead of 20

Eli
I don't think that's a good approach: it's much more important to write good, modular code rather than worry about a few extra lines here and there. Go back and optimise when the the app is complete - and if tests show you really need to in the first place.

For the record, I'll normally have at least 500 lines of submissions checking code for each form. That's not all the fom handling code, just the bits that examine the submission. Php is pretty fast.

The Strategy pattern article on phppatterns.com might be worth a look. The example code shows Strategy applied to form validation.

Posted: Wed Mar 31, 2004 5:12 pm
by lazy_yogi
I've found what I think to be the most generic form validation, and uses more than one line per field, but still keeps the number down.
Similar to pears forms class.

You have

Validator->addRule(field, "fieldName", "required","errorMsg")
Validator->addRule(field, "fieldName", "digitsOnly","errorMsg")
etc...

Post number 8 here has an exceptional implementation of it:
http://www.sitepoint.com/forums/showthr ... did=114185

The interface is perfect, as is the implementation and class design and interaction. It doesn't have all the rules implemented in that post tho. I might have to do that if I can't get similar code.

Posted: Thu Apr 01, 2004 2:15 pm
by ghost007
Hi yogi,

long time I have not been around on the forum but the script I'm working on has evolved alot since our last discussion.

I have created a form validation script that can be used as this:

Code: Select all

$cfgx->errcheck->numericCheck (mandatory,$param_to_check,errornr,allow);
numericCheck -> or check you want to do.
mandatory = 1 or 0;
errornr = array nr of error in error_msg file
allow = extra reg_exp you want to add to check

The same class has also a function to be used as error checking routine within the script. The errors will not be outputed into the page with the form but will redirect user to error.php.

If you'r still looking for error checking class just let me know.

btw the whole script and some of the error class code can be found here:
viewtopic.php?t=16283

cheers

Siech

Posted: Fri Apr 02, 2004 2:23 am
by lazy_yogi
ghost007 wrote:I have created a form validation script that can be used as this:

Code: Select all

$cfgx->errcheck->numericCheck (mandatory,$param_to_check,errornr,allow);
numericCheck -> or check you want to do.
mandatory = 1 or 0;
errornr = array nr of error in error_msg file
allow = extra reg_exp you want to add to check
Looks very similar to the one I'm thinking of using.

ghost007 wrote:The same class has also a function to be used as error checking routine within the script. The errors will not be outputed into the page with the form but will redirect user to error.php.

If you'r still looking for error checking class just let me know
Nah, with php 5 finally out, I'll be using exceptions for all errors. They are the ideal way to handle errors - which was one of the main things lacking in php.

I wouldn't mind checking out some of ur validation class code if ur willing to release it

Regards,
Eli

Posted: Fri Apr 02, 2004 1:51 pm
by ghost007
Yeah PHP 5 is nice but considering the price that I pay for my hosting I don't think it will be made available for me in the near future :(.

No prob for the code. just let me know in which check(s) you are interested.

cheers
Siech

Posted: Sat Apr 03, 2004 10:54 am
by ghost007
no prob yogi. here ya go:

Code: Select all

<?php

class errorcheck extends backend{
		
	var $special_chars="[]\.\,\:\;\?\!\(\)"''\{\}\&\@"; // Allowed punctation marks
	//var $err = array();
	var $prnt_errors = array();
	var $fatal;
		
		function set_error ($nr,$noheader = 0){
			$count = count ($this->err);
			if ($noheader != 1)
			{
				if ($count == 0)$this->err[] = "99";
			}
			if ($this->fatal == 1) $this->error_page(__LINE__,__FILE__,$nr,3);
			else $this->err[] = $nr;
		}
		
		function parse_error ($field){
			include ("error_msg.php");
			$count = count ($this->err);

			for ($x=0; $x<$count; $x++)
			{
				$this->prnt_errors[] [$field] = $incl_errors [$this->err[$x]]."<br>";
			}
			$this->err = "";
			return $this->prnt_errors;
		}

		function alphaCheck($mandatory,$value,$errornr, $allow = '')
		{
			if ($mandatory == 1 || $value != "")
			{
				if (preg_match('/^[a-zA-Z'.$allow.']+$/', $value)) return 1; 
				else $this->set_error ($errornr);
			}
			else return 1;
		}
		
		function numericCheck($mandatory,$value,$errornr, $allow = '')
		{
			if ($mandatory == 1 || $value != "")
			{
				if (preg_match('/^[0-9'.$allow.']+$/', $value)) return 1; 
				else $this->set_error ($errornr);
			}
			else return 1;
		}
		
		function alphaNumericCheck($mandatory,$value,$errornr, $allow = '')
		{
			if ($mandatory == 1 || $value != "")
			{
				if(preg_match('/^[a-zA-Z0-9'.$allow.']+$/', $value))return 1;
				else $this->set_error ($errornr);
			}
			else return 1;
		}
		
		function emailCheck($mandatory,$value,$errornr)
		{
			if ($mandatory == 1 || $value != "")
			{
				$pattern = '/^([a-zA-Z0-9])+([\.a-zA-Z0-9_-])*@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-]+)+/';
				if(preg_match($pattern, $value))return 1;
				else $this->set_error ($errornr);
			}
			else return 1;
		}
		
		//check website url!
		function verifyurl($mandatory,$value,$errornr){ 
		if ($value == $this->server_url) return 1;
			if ($mandatory == 1 || $value != "")
			{
				$regexp = "^(https?://)?(([0-9a-z_!~*'().&=+$%-]+:)?[0-9a-z_!~*'().&=+$%-]+@)?(([0-9]{1,3}\.){3}[0-9]{1,3}|([0-9a-z_!~*'()-]+\.)*([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\.[a-z]{2,6})(:[0-9]{1,4})?((/?)|(/[0-9a-z_!~*'().;?:@&=+$,%#-]+)+/?)$"; 
				//qualified domain 
				if (eregi( $regexp, $value )){ 
					// No http:// at the front? lets add it. 
					if (!eregi( "^https?://", $value )) $value = "http://" . $value; 
					// If it's a plain domain or IP there should be a / on the end 
					if (!eregi( "^https?://.+/", $value )) $value .= "/"; 
					// If it's a directory on the end we should add the proper slash 
					// We should first make sure it isn't a file, query, or fragment 
					if ((eregi( "/[0-9a-z~_-]+$", $value)) && (!eregi( "[\?;&=+\$,#]", $value))) $value .= "/"; 
					//return success;
					return 1;
				} 
				else $this->set_error ($errornr);
			}
			else return 1;
		} // END Function verifyurl 
		
}


?>

Posted: Sat Apr 03, 2004 11:40 am
by McGruff
If you check the design section on http://www.phppatterns.com there's a nice article about using the Strategy pattern for validators. With Strategy, you can call just what you need rather than putting them all in one big class.

Posted: Sat Apr 03, 2004 9:00 pm
by lazy_yogi
Ah ... thanx for the look at the code ghost.

Interesting solution using $allow to add regex characters.
That's a problem I'm dealing with, since name can be any alpha char but can contain hyphens and apostrphe's

The problem is I'm trying to auto generate the error message from the validation type.

For example, if it fails the alpha check, then error msg will be $fieldname.' only allows alphabetic characters.
But with $allow as you use it, you can't add to the error message.

Also, as McGruff said, the strategy patter is quite nice for this problem.
I think I'll be going with the code from the link I posted above from sitepoint. It's based on pear forms module which has nice validation and filter methods.

But then i still have the problem of name allowing hyphens and apostrophe's and similar probs with other fields.

I think I'd just have to use disallowDigits, and disallowPuntuation for that case.

Thanks again for giving me a look at ur code tho - gives me another view.

Eli

Posted: Sat Apr 03, 2004 9:05 pm
by markl999
Slightly offtopic, but the ctype functions come in handy for validation, saves having to invoke the regex engine.