我需要一个php验证器类来验证用户输入。
我希望它能够接受一个由字段=>值组成的assoc数组,比如:
array(
"username" => "Alex",
"email_address" => "@@#3423£alex@my.mail.com"
);
然后返回一系列错误,如下所示:
array(
"username" => "",
"email_address" => "Invalid Email Address"
);
但我真的很纠结我到底该怎么做!
我读过无数关于PHP验证器的页面,并了解到最好的方法是使用策略模式。但是我不知道怎么做??
就像。。。这就是我目前所掌握的:
class Validator {
private
$_errors,
$_fields,
static private $_map = array (
"firstname" => "name",
"surname" => "name",
"agency_name" => "name",
"agency_office" => "name",
"username" => "username",
"email_address" => "email_address",
);
public function __construct( array $fields ) {
$this->_fields = $fields;
}
public function validate() {
foreach ( $this->_fields as $field => $value ) {
if ( method_exists( __CLASS__, self::$_map[$field] ) ) {
if ( in_array( $field, self::$_map ) ) {
$this->{self::$_map[$field]}( $field, $value );
}
}
else {
die( " Unable to validate field $field" );
}
}
}
public function get_errors() {
return $this->_errors;
}
private function name( $field, $value ) {
if ( !preg_match( "/^[a-zA-Z]{2,50}$/", $value ) ) {
$this->errors[$field] = "Invalid. Must be 2 to 50 alphanumerical characters";
}
}
private function username( $field, $value ) {
if ( !preg_match( "/^[a-zA-Z0-9_'-]{10,50}$/", $value ) ) {
$this->errors[$field] = "Invalid. Must be 10 to 50 characters. Can contain digits, characters, _ (underscore) and - (hyphen)";
}
}
private function password( $field, $value ) {
if ( !preg_match( "/^[a-zA-Z0-9'.'-]{8,30}$/", $value ) ) {
$this->_errors[$field] = "Invalid. Must be 8 to 30 characters. Can contain digits, characters, . (full stop) and - (hyphen)";
}
}
private function email_address( $field, $value ) {
if ( !filter_var( $value, FILTER_VALIDATE_EMAIL ) ) {
$this->_errors[$field] = "Invalid Email Address";
}
}
}
问题是,它甚至没有考虑数据库连接,例如,已经注册的用户名,
也是不匹配密码
我现在刚刚遇到了编码器阻塞,它在内部摧毁了我:(
有人能解释一下每个类需要做的类和函数吗?
我真的需要输入和输出的格式已经解释过了!
非常感谢互联网人!
作为MVC的一部分,我解决了同样的问题。我可以给你一个清单,但在几行中试着描述如何。
我得到了3个基类Form
、Validator
、Field
,这些类的每个对象都通过一个YAML文件进行配置,其结构如下:
name: // field name
i18n: [ ru, en ] // is the field i18n
field:
class: Base // class to use for field
options: { specific_save: true } // options from available (defined in class)
attributes: { } // attributes, for HTML rendering
validator:
class: String // Class to validate with
options: { required: true, max: 100 } // options for validator
因此,让我们从Form
开始,当对象构建时,表单采用上面描述的YAML文件,并且由于该配置而创建字段。类似这样的东西:
// Imlement this function to configure form;
foreach ($this->_config as $f => $c)
{
$class = '''Lighty''Form''Field''' . (isset($c['field']['class']) && $c['field']['class'] ? $c['field']['class'] : 'Base');
$o = isset($c['field']['options']) && is_array($c['field']['options']) ? $c['field']['options'] : array();
$a = isset($c['field']['attributes']) && is_array($c['field']['attributes']) ? $c['field']['attributes'] : array();
$field = new $class($this, $o, $a);
$field->setName($f);
$class = '''Lighty''Form''Validator''' . (isset($c['validator']['class']) && $c['validator']['class'] ? $c['validator']['class'] : 'Base');
$o = isset($c['validator']['options']) && is_array($c['validator']['options']) ? $c['validator']['options'] : array();
$m = isset($c['validator']['messages']) && is_array($c['validator']['messages']) ? $c['validator']['messages'] : array();
$field->setValidator($validator = new $class($field, $o, $m));
if (isset($this->_options['default'][$f]))
{
$field->setValue($this->_options['default'][$f]);
}
if (isset($c['i18n']))
{
if (is_array($c['i18n']))
{
$field->setCultures($c['i18n']);
}
$field->setI18n((bool) $c['i18n']);
}
$this->addField($field);
因此,现在我们有了带有字段和每个字段的验证器的表单,然后为了验证,我使用了以下机制:
Form遍历每个字段,调用validate()
方法,Field(获取绑定值)调用绑定Validator的validate($value)
方法,传递存储的值。在这个方法中,Validator调用validateOption()
方法,其中每个选项都有一个简单的开关,例如:
switch ($o)
{
case 'required':
$valid = $state && trim($value) != '' || !$state;
break;
default:
return 'warning(sprintf('Undefined validator option "%s" in %s validator class', $o, get_class($this->getField()->getValidator())), null);
}
在这里,您可以看到对必需选项的验证。若我需要更多的验证器,我会扩展Base验证器的类,定义更多的选项,并重新定义validateOption()
,其中在选项的switch
的default
语句中放入parent::validateOption()
。所以指定的选项在新的类中进行验证,旧的选项在基验证器类中进行。
如果有任何问题。。。不客气。