Интересный вопрос. Думаю, я бы создал класс со статическим полем для хранения всех правил.
Потребуется одна функция для прямой проверки ввода или возврата функции валидатора для использования на стороне сервера, а другая - для доступа к ajax для получения списка правил, которые будут протестированы в javascript с eval.
Нет никаких причин, $rulesPHP
и rulesJS
должны быть одинаковыми. На самом деле, я не вижу смысла в проверке одной и той же вещи на каждом конце - возможно, вы захотите проверить разные вещи.
class Validation
{
protected static $rulesPHP =
array(
'positiveInteger' => array('($x === int($x))', '($x > 0)'),
'alphanumericString' => array(....)
);
protected static $rulesJS =
array(
'positiveInteger' => array('(x === int(x))', '(x > 0)'),
'alphanumericString' =>array(..... )
);
public static getValidatorPHP($type)
{
if (!isset($rulesPHP[$type])) return false;
$exp = explode(' && ', self::$rulesPHP[$type]);
return function($x) use ($exp)
{
return eval($exp);
};
}
public static getJsRules($type)
{
if (!isset($rulesJS[$type])) return false;
$exp = explode(' && ', self::$rulesJS[$type]);
return $exp;
}
}
используется в другом файле:
$posIntValidator = Validation::getValidatorPHP('positiveInteger');
$posIntValidator($_POST['text1']);
Ajax с ruleaccessor.php:
$t = $_GET['type'];
$out = Validation::getJsRules($t);
echo $out;
JavaScript:
function getValidator(type)
{
var rules;
$.get('/ruleaccessor.php?type=' + type, function(in) {rules = in;});
return function(x){return eval(rules);};
}
validatePosInt = getValidator('positiveInteger');
validatePosInt($('#text1').val());
Конечно, вам придется решить, как вы хотите обрабатывать вещи, которые не проверяются. А если вы хотите иметь разные сообщения для разных ошибок валидации, вам придется хранить сообщение вместе с каждым правилом, и вы не сможете просто разобрать их вместе.
Это далеко не развитая идея, но, надеюсь, общий дизайн может вас куда-нибудь привести.