我试图让该检查的密码字段的复杂性,用户登记表。 我写了一个自定义验证根据做这个文件 。 此文件居住在用户的\ src \用户\验证我的“用户”模块。
<?php
namespace User\Validator;
use Zend\Validator\AbstractValidator;
class PasswordStrength extends AbstractValidator {
const LENGTH = 'length';
const UPPER = 'upper';
const LOWER = 'lower';
const DIGIT = 'digit';
protected $messageTemplates = array(
self::LENGTH => "'%value%' must be at least 6 characters long",
self::UPPER => "'%value% must contain at least one uppercase letter",
self::LOWER => "'%value% must contain at least one lowercase letter",
self::DIGIT => "'%value% must contain at least one digit letter"
);
public function isValid($value) {
... validation code ...
}
}
我的问题出现在试图在我的用户登记表使用此验证。 我试图在Module.php配置它添加验证到的ServiceManager。
public function getServiceConfig() {
return array(
'invokables' => array(
'PasswordStrengthValidator' => 'User\Validator\PasswordStrength'
),
);
}
然后我把它添加到user.php的输入滤波器。
public function getInputFilter() {
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
$factory = new InputFactory();
$inputFilter->add($factory->createInput(array(
'name' => 'username',
'required' => true,
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 1,
'max' => 100,
),
),
),
)));
$inputFilter->add($factory->createInput(array(
'name' => 'password',
'required' => true,
'validators' => array(
array(
'name' => 'PasswordStrengthValidator',
),
),
)));
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
然而,当我访问的形式和点击提交按钮,我得到一个ServiceNotFoundException的。
Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for PasswordStrengthValidator
有没有与我的ServiceManager配置有问题? 我甚至不知道这是摆在首位,以使用自定义验证程序的适当方式。 我发现很多使用ZF1的例子,但我发现从来没有超越验证程序的书面延伸,以解决其与整合形式等任何意见,将不胜感激的文档和ZF2例子。
Answer 1:
您正试图在你的例子使用“短名称”验证加载只有当你注册一个简短的名称/别名与验证插件管理器(作品Zend\Validator\ValidatorPluginManager
)第一。
一种可以替代的(和我的方式做到这一点)是创建表单过滤器对象时,注入必要的自定义验证器的实例。 这是ZfcUser做它的方式:
// Service factory definition from Module::getServiceConfig
'zfcuser_register_form' => function ($sm) {
$options = $sm->get('zfcuser_module_options');
$form = new Form\Register(null, $options);
$form->setInputFilter(new Form\RegisterFilter(
new Validator\NoRecordExists(array(
'mapper' => $sm->get('zfcuser_user_mapper'),
'key' => 'email'
)),
new Validator\NoRecordExists(array(
'mapper' => $sm->get('zfcuser_user_mapper'),
'key' => 'username'
)),
$options
));
return $form;
},
来源: https://github.com/ZF-Commons/ZfcUser/blob/master/Module.php#L100
这里,两个ZfcUser\Validator\NoRecordExists
验证器实例(一个用于电子邮件,一个用于用户名)被注入到输入滤波器对象的登记表(的构造ZfcUser\Form\RegisterFilter
)。
然后,里面ZfcUser\Form\RegisterFilter
类,校验器被添加到元素定义:
$this->add(array(
'name' => 'email',
'required' => true,
'validators' => array(
array(
'name' => 'EmailAddress'
),
// Constructor argument containing instance of the validator
$emailValidator
),
));
来源: https://github.com/ZF-Commons/ZfcUser/blob/master/src/ZfcUser/Form/RegisterFilter.php#L37
我相信,另一种选择是使用完全合格的类名作为验证名称(即:“用户\验证\密码强度”,而不仅仅是“PasswordStrengthValidator”),虽然我从来没有尝试这个自己。
Answer 2:
你可以试试这个解决办法... registrer在Module.php但功能getValidatorConfig或下键module.config.php“验证器”你的验证。
public function getValidatorConfig() {
return array(
'invokables' => array(
'PasswordStrengthValidator' => 'User\Validator\PasswordStrength'
),
);
}
然后在你的user.php的,试试这个:(但你必须访问的服务定位器,你可以从UserFactory等注入的话)
$validatorManager = $this->getServiceLocator()->get('ValidatorManager');
// here you can test $validatorManager->get('PasswordStrengthValidator');
$validatorChain = new ValidatorChain();
$validatorChain->setPluginManager($validatorManager);
$inputFilter = new InputFilter();
$inputFilter->getFactory()->setDefaultValidatorChain($validatorChain);
这对我的作品。
马丁
Answer 3:
删除您可调用的配置。
并修改您的验证设置:
$inputFilter->add($factory->createInput(array(
'name' => 'password',
'required' => true,
'validators' => array(
array(
'name' => 'User\Validator\PasswordStrength',
),
),
)));
为我工作。
Answer 4:
Rufinus解决方案的工作般的魅力。 步骤我跟着使用自定义的验证中(在我的案件的URL验证来检查网站确实存在):
1)在module.config.php
'validators' => array(
'invokables' => array(
'UrlValidator' => 'Application\Validators\UrlValidator'
),
)
2)在路径的应用/ SRC /应用/验证器/ UrlValidator.php
namespace Application\Validators;
use Zend\Validator\AbstractValidator;
class UrlValidator extends AbstractValidator{
const NOTURL = 'NOTURL';
protected $messageTemplates = array(
self::NOTURL => 'Value should be a valid URL',
);
public function __construct(array $options = array()){
parent::__construct($options);
}
public function isValid($value){
$this->setValue($value);
if (!$this->validateurl($value)) {
$this->error(self::NOTURL);
return false;
}
return true;
}
private function validateurl($url) {
$ch = curl_init(); // initialize curl handle
curl_setopt($ch, CURLOPT_URL, $url); // set url to post to
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 1);
$result = curl_exec($ch);
$info = curl_getinfo($ch);
$code = $info['http_code'];
curl_close($ch);
if ($code == substr($code, 0, 1) || substr($code, 0, 1) == '4' || substr($code, 0, 1) == '5') {
return false;
} else {
return true;
}
}
}
3)在形式
$inputFilter->add($factory->createInput(array(
'name' => 'url',
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'messages' => array(
'isEmpty' => 'URL is required'
)
)
),
array(
'name'=>'Application\Validators\UrlValidator'
)
)
)));
额外的)如果你想在应用程序(即一个控制器动作内),您可以从ValidatorManager插件检索任何地方使用它:
$urlValidator = $this->getServiceLocator()->get('ValidatorManager')->get('UrlValidator');
Answer 5:
是的,正如孔蒂或表述为工厂的情况下,你需要注入一个业务经理,或学说实体管理器在下面的例子中也可以是可调用的。 这种方式是非常优雅的解决方案:
'validators' => array(
'invokables' => array(
//'emailExist' => 'Application\MyValidation\EmailExistValidator',
),
'factories' => array(
'emailExist' => function ($vm) {
$serviceLocator = $vm->getServiceLocator();
$emailExistValidator = new \Application\MyValidation\EmailExistValidator();
$doctrineEntityManager = $serviceLocator->get('Doctrine\ORM\EntityManager');
$emailExistValidator->setObjectManager($doctrineEntityManager);
return $emailExistValidator;
},
),
),
文章来源: Zend Framework 2 Custom Validators for Forms