Я, делаю php класс проверки с sub классами, которые расширяют его, например, мобильные, пригород, credit_card, ect
таким образом идея - Вы, может звонить
$validation = new Validation('mobile');
$valid = $validation->validate($number);
$validation->type('suburb');
$valid2 = $validation->validate($suburb);
теперь моя идея для того, чтобы сделать это имеет
class Validation() {
private $v_type = null;
function __construct($type) {
$this->type($type);
}
public function type($type) {
$this->v_type = new $type();
}
public function validate($info) {
return $this->v_type->validate($info);
}
}
как очень простой пример
но есть ли лучший способ сделать это?
Вы можете сделать это так, но это можно улучшить. Иметь собственную логику валидации в капсуле фактических валидаторов - это хорошо. Расширение их из базового класса - нет. Давайте вместо этого реализуем интерфейс. Таким образом, любой класс может быть валидатором.
interface IValidate
{
public function validate($value);
}
Тогда ваши валидаторы будут выглядеть так:
class IsNumeric implements IValidate
{
public function validate($value)
{
return is_numeric($value);
}
}
и
class GreaterThan implements IValidate
{
protected $_value;
public function __construct($value)
{
$this->_value = $value;
}
public function validate($value)
{
return $value > $this->_value;
}
}
У вас все еще будет основной класс валидатора. В отличие от вашего примера, валидатор ниже принимает несколько валидаторов, что позволит вам создать цепочку фильтров.
class Validator implements IValidate
{
protected $_validators;
public function addValidator(IValidate $validator)
{
$this->_validators[] = $validator;
return $this;
}
public function validate($value)
{
foreach($this->_validators as $validator) {
if ($validator->validate($value) === FALSE) {
return FALSE;
}
}
return TRUE;
}
}
И это можно было бы использовать как:
$validator = new Validator;
$validator->addValidator(new IsNumeric)
->addValidator(new GreaterThan(5));
var_dump( $validator->validate('ten') ); // FALSE
var_dump( $validator->validate('10') ); // TRUE
var_dump( $validator->validate('1') ); // FALSE
Вышеупомянутое в значительной степени является шаблоном команды . И поскольку валидатор также реализует IValidate, он также является Composite . Вы можете взять цепочку валидатора сверху и сложить ее в другую цепочку валидатора, например
$numericGreaterThanFive = new Validator;
$numericGreaterThanFive->addValidator(new IsNumeric)
->addValidator(new GreaterThan(5));
$otherValidator = new Validator;
$otherValidator->addValidator(new Foo)
->addValidator(new Bar)
->addValidator($numericGreatherThanFive);
Для удобства вы можете добавить статический фабричный метод для создания валидаторов с фактическими объектами команды валидации (как показано в другом месте).
Замечание: Zend Framework уже имеет большое количество валидаторов, на которых вы можете построить . Поскольку ZF является библиотекой компонентов, вы можете использовать их без необходимости переноса всего приложения в ZF.
...
public function type($type) {
return new self($type);
}
...
Примечание: Этот метод каждый раз возвращает новый экземпляр вашего класса Validator, поэтому лучше использовать паттерн Factory, как предложил Деннис, или не привязывать новый Validator к методу type().
Обычно вы делаете подобные вещи, используя паттерн Factory, что-то вроде этого:
class ValidatorFactory {
public static function get($type) {
$validator = "Validator_$type";
return new $validator();
}
}
$valid = ValidatorFactory::get('mobile')->validate($number);
Конечно, потребуется некоторая проверка ошибок и тому подобное, но вы должны понять идею
.