Page 1 of 1
help getting base class to recognize extending class values
Posted: Tue Dec 11, 2007 5:33 am
by s.dot
This is a form validation class that I'm trying out. It's really nothing fancy, i'm just getting started on it, but already having troubles.
Code: Select all
<?php
/**
* Form validation base class
*/
class formValidator
{
//container for rules
protected $_rules = array();
/**
* Method to add rules
*/
public function addRule(formValidator $rule)
{
$rule->_add();
}
public function validate()
{
//
}
public function show()
{
echo '<pre>';
print_r($this->_rules);
echo '</pre>';
}
}
class formValidatorRequired extends formValidator
{
private $_field;
public function __construct($field)
{
$this->_field = $field;
}
protected function _add()
{
if (is_array($this->_field))
{
foreach ($this->_field AS $field)
{
$this->_rules['required'][] = $field;
}
} else
{
$this->_rules['required'][] = $this->_field;
}
}
}
class formValidatorLength extends formValidator
{
private $_field;
private $_minLength;
private $_maxLength;
public function __construct($field, $minLength, $maxLength)
{
$this->_field = $field;
$this->_minLength = $minLength;
$this->_maxLength = $maxLength;
}
protected function _add()
{
$this->_rules['length'][] = array(
$field => array(
'minLength' => $this->_minLength,
'maxLength' => $this->_maxLength
)
);
}
}
And I am calling it like this:
Code: Select all
if (!empty($_POST['action']) && ($_POST['action'] == 'register'))
{
//form validation object
require_once 'class/formValidator.php';
$formValidator = new formValidator();
//add rules
$formValidator->addRule(
new formValidatorRequired(array('username', 'password', 'passwordConfirm', 'email', 'emailConfirm'))
);
$formValidator->show();
}
I added the show() method just to see if the rules had been added to the formValidator object. But it always prints out an empty array. What am I doing wrong here?
Posted: Tue Dec 11, 2007 10:00 am
by s.dot
basically, formValidatorRequired::_rules is getting set, but I need formValidator::_rules to be set
Posted: Tue Dec 11, 2007 10:03 am
by feyd
_add(), which needs to be defined in the base, technically, in the children manipulates only the child class, not the containing class, as they are separate objects.
You need a method (or modify one) to take a formValidator that will be injected with the data, or rethink what formValidator means, versus the children you have built thus far.
You are calling them rules, so are they supposed to be formValidators in their own right, or rules that the formValidator follows?
Posted: Tue Dec 11, 2007 10:16 am
by s.dot
Basically I was thinking that since the rule classes extends formValidator, that any reference to $this->_rules would reference the member in the formValidator class, rather than creating a member in the rule classes.
What I want to end up with is a member in class formValidator that looks like:
Code: Select all
Array
(
required => Array(
[0] => field1
[1] => field2
[2] => field3
)
length => Array
(
username => Array
(
minlength => 3,
maxlength => 25
)
password => Array
(
minlength => 6,
maxlength => false
)
)
So that my validate() method can iterate through the array and perform necessary checks.
How that translates into what you just said, I don't know. Basically I didn't understand:
You need a method (or modify one) to take a formValidator that will be injected with the data, or rethink what formValidator means, versus the children you have built thus far.
Posted: Tue Dec 11, 2007 10:41 am
by s.dot
o0o I got it.
The method addRule() needs to add onto the member
Code: Select all
public function addRule(formValidator $rule)
{
$this->_rules = array_merge($this->_rules, $rule->_add());
}
And the $rule->_add() methods need to return data (an array).
Posted: Tue Dec 11, 2007 11:11 am
by s.dot
Okay, so this is what I have so far. My question now is if my logic and the way I set up the objects is good? This isn't really critique, because I don't know if what I have is right. The only thing I can think of is that I'm expecting the form to be posted via $_POST.
Is there anything I should be doing differently?
Code: Select all
<?php
require_once 'class/formvalidator/rule/length.php';
require_once 'class/formvalidator/rule/required.php';
require_once 'class/formvalidator/rule/regex.php';
/**
* Form validation base class
*/
class formValidator
{
//container for rules
protected $_rules = array();
/**
* Method to add rules
*/
public function addRule(formValidator $rule)
{
$this->_rules = array_merge_recursive($this->_rules, $rule->_add());
}
public function validate()
{
if ($this->_validateRequired() && $this->_validateLength() && $this->_validateRegex())
{
return true;
}
return false;
}
private function _validateRequired()
{
//required rules
if (!empty($this->_rules['required']))
{
foreach ($this->_rules['required'] AS $required)
{
if (empty($_POST[$required]) || (trim($_POST[$required]) == ''))
{
return false;
}
}
}
return true;
}
private function _validateLength()
{
//length rules
if (!empty($this->_rules['length']))
{
foreach ($this->_rules['length'] AS $field => $length)
{
$strlen = strlen($_POST[$field]);
if (($strlen < $length['minLength']))
{
return false;
}
if ($length['maxLength'] && ($strlen > $length['maxLength']))
{
return false;
}
}
}
return true;
}
private function _validateRegex()
{
//regex rules
if (!empty($this->_rules['regex']))
{
foreach ($this->_rules['regex'] AS $field => $pattern)
{
if (!preg_match($pattern, $_POST[$field]))
{
return false;
}
}
}
return true;
}
public function show()
{
echo '<pre>';
print_r($this->_rules);
echo '</pre>';
}
}
Code: Select all
<?php
class formValidator_Rule_Required extends formValidator
{
private $_field;
public function __construct($field)
{
$this->_field = $field;
}
protected function _add()
{
$ret = array();
if (is_array($this->_field))
{
foreach ($this->_field AS $field)
{
$ret['required'][] = $field;
}
} else
{
$ret['required'] = $this->_field;
}
return $ret;
}
}
Code: Select all
<?php
class formValidator_Rule_Length extends formValidator
{
private $_field;
private $_minLength;
private $_maxLength;
public function __construct($field, $minLength=false, $maxLength=false)
{
$this->_field = $field;
$this->_minLength = $minLength;
$this->_maxLength = $maxLength;
}
protected function _add()
{
$ret = array();
$ret['length'] = array(
$this->_field => array(
'minLength' => $this->_minLength,
'maxLength' => $this->_maxLength
)
);
return $ret;
}
}
Code: Select all
<?php
class formValidator_Rule_Regex extends formValidator
{
private $_field;
private $_regex;
public function __construct($field, $regex)
{
$this->_field = $field;
$this->_regex = $regex;
}
protected function _add()
{
$ret = array();
$ret['regex'] = array($this->_field => $this->_regex);
return $ret;
}
}
And I'm calling it like this:
Code: Select all
//form validation object
require_once 'class/formvalidator/formvalidator.php';
$fv = new formValidator();
//add rules
$fv->addRule(new formValidator_Rule_Required(array('username', 'password', 'passwordConfirm', 'email', 'emailConfirm')));
$fv->addRule(new formValidator_Rule_Length('username', 3, 25));
$fv->addRule(new formValidator_Rule_Length('password', 6));
$fv->addRule(new formValidator_Rule_Regex('username', '/[\w]+/'));
var_dump($fv->validate());
$fv->show();
Basically I'm second-guessing everything I'm doing. =/ I think it's because whenever I bring up an OO subject, there's so many different ways of doing things that I lose interest halfway through the topic because I'm completely lost. I'm learning slowly but surely.
So far the validator is working good. I should implement some tests (note to maugrim

).
Posted: Tue Dec 11, 2007 1:06 pm
by feyd
Personally, I would actually shift the validation routines to the rules themselves. Allowing the formValidator to simply facilitate the connection between data and validator. This allows you to use custom or "odd" forms of validation that the now base doesn't support. The reason why I don't like it now is that the formValidator knows too much about the children it seems, and the children know too much about the parent.
I think they should be entirely separate classes (no inheritance between them.)
Posted: Tue Dec 11, 2007 6:48 pm
by stereofrog
class formValidator_Rule_Regex extends formValidator
doesn't feel right to me. Validator is what manages and applies Rules (which in turn know nothing about Validator).