Когда я читал ваш пост, у меня возник вопрос о том, что вы пишете:
Почему, вместо проверки формы, вы не проверяете объекты вашей модели?Я имею в виду, что с точки зрения ООП вещи вашей модели (или доменные объекты) - это те, кто знает, какие данные являются действительными или нет для каждого из их атрибутов.Не делайте этого, и использование этой логики в пользовательском интерфейсе делает ваш дизайн хрупким, зависимым от пользовательского интерфейса и более сложным в обслуживании.Если вы добавите новый атрибут к одному из объектов вашей модели, вам также придется изменить валидатор формы.
Если вы используете Проверка объектов , идея состоит в том, что объектне может быть создан в недопустимом состоянии.Если вы попытаетесь изменить его с неверными данными, будет сгенерировано исключение.Это облегчает работу с формами.Единственное, что вам нужно сделать, это заполнить ваши объекты и наблюдать за исключениями, возникающими в этом процессе.Это только идея, чтобы вы начали и увидели другой способ решения этой проблемы.
Относительно вашего вопроса о Проверка форм , как говорили другие парни, всегда лучше не изобретать зановои перейдите к существующей, проверенной, проверочной среде.
Однако, если вам интересно это, вот один из многих способов , вы можете сделать это:
Давайте пройдемся по вещам, которые вам нужны: вы говорите о форме , которая должна быть подтверждена с одним или несколькими проверка функции.Затем вы говорите о функции, которая сообщает вам, прошла ли форма проверку или нет , и в результате вы получили список ошибок, найденных во время проверкифаза .
Когда вы говорите об ООП, путь состоит в том, чтобы дать каждому понятию или идее сущность вашей проблемной области (области проверки формы) через класс, который представляет ее, чтосмоделируйте поведение, которое у них есть.
Итак, естественно подумать о FormValidator
классе со списком ValidationRule
экземпляров, где каждый из них взаимодействует в процессе валидации.Этот процесс проверки выполняется путем вызова функции validate
из FormValidator
.Кроме того, каждый ValidationRule
даст в результате вызова своего собственного validate
метода экземпляр класса ValidationRuleResult
, который сообщает, была ли проверка успешной, вместе с сообщением об ошибке и дополнительными данными (еслинеобходимо) о проверке.После оценки всех правил проверки метод validate
класса FormValidator
вернет экземпляр класса ValidationResult
, который суммирует все результаты проверки оцененных правил с предоставлением списка найденных ошибок.
Чтобы понять это, вот пример модели, о которой мы говорим:
Пример реализации
Отказ от ответственности: пожалуйстаимейте в виду, что, как и любой дизайн, он может содержать недостатки.Следующее предназначено, чтобы помочь вам решить вашу проблему, а не быть полным решением.
class FormValidator {
private $_validationRules;
function __construct() {
$this->_validationRules = array();
}
// Registers a new validation rule
function addRule($aValidationRule) { $this->validationRules[] = $aValidationRule; }
// Validates $aForm, evaluating each of the $_validationRules defined
function validate($aForm) {
$aValidationResult = new ValidationResult();
foreach($this->_validationRules as $aValidationRule) {
$aValidationRuleResult = $aValidationRule->validate($aForm);
$aValidationResult->addResult($aValidationRuleResult);
}
return $aValidationResult;
}
}
abstract class ValidationRule {
private $_fieldName;
// The form's field name to be validated
function __construct($aFieldName) {
$this->_fieldName = $aFieldName;
}
function fieldName() { return $this->_fieldName; }
// Returns an instance of ValidationResult describing the result of evaluating the ValidationRule in $aForm.
abstract public function validate($aForm);
}
class ValidationResult {
private $_validationRuleResults;
function __construct() {
$this->_validationRuleResults = array();
}
// Registers a validation rule result
function addResult($aValidationRuleResult) {
$this->_validationRuleResults[] = $aValidationRuleResult;
}
// Returns the list of the error messages of the validation rule results that did't passed
function errorsFound() {
$errors = array();
foreach($this->validationRuleResults as $aValidationResult) {
if ($aValidationResult->passed()) continue;
$errors[] = $aValidationResult->errorMessage();
}
return $errors;
}
// Tells whether all the validation rule results passed or not
function validationPassed() {
foreach($this->validationRuleResults as $validationResult) {
if ($validationResult->passed() == false) return false;
}
return true;
}
}
class ValidationRuleResult {
private $_passed, $_error_message;
function __construct($passed) {
$this->_passed = $passed;
$this->_error_message = '';
}
// Tells whether the form passed this validation rule or not
public function passed() { return $this->_passed; }
public function
// The error message should be empty if passed to avoid confusion
public function errorMessage { return $this->passed() ? '' : $this->_error_message; }
public function setErrorMessage($anErrorMessage) { $this->_error_message = $anErrorMessage; }
}
Вы можете создать правило проверки следующим образом:
class NotEmptyValidationRule extends ValidationRule {
public function validate($aForm) {
$fieldName = $this->fieldName();
$fieldValue = $aForm[$fieldName];
$passed = !empty($fieldValue);
$result = new ValidationRuleResult($passed);
if (!$passed) {
$result->setErrorMessage("$fieldName cannot be empty");
}
return $result;
}
}
Некоторые замечания:
- Я предполагаю, что $ aForm является ассоциативным массивом имени / значения поля
- Вы можете заметить, что если правило валидации проходит, результат не используется (как
ValidationResult
класс работает только на тех результатах, которые не прошли).Помните, что это образец только с целью помочь вам, а не полное решение.
Использование
$rule = new NotEmptyValidationRule('name');
$validator = new FormValidator();
$validator->addRule($rule);
$aForm = $__POST['myForm'];
$validationResult = $validator->validate($aForm);
if ($validationResult->validationPassed()) {
$errorsFound = $validationResult->errorsFound();
// do something with the $errorMessage
$errorMessage = array_join('<br/>', $errorsFound);
}