您可能最终会得到这样的自定义验证器:
class MyCustomValidator extends ZendAbstractValidator
{
const FIELDS_EMPTY = 'fieldsEmpty';
/**
* Error messages
*
* @var array
*/
protected $abstractMessageTemplates = [
self::FIELDS_EMPTY => "Vale for %field1% is required and can't be empty, if %field2% is not set.",
];
/**
* Variables which can be used in the message templates
*
* @var array
*/
protected $abstractMessageVariables = [
'field1' => 'field1',
'field2' => 'field2',
];
/**
* Value of the field
* @var mixed
*/
protected $value;
/**
* Name of the first field to check, which the validator is bind to
* @var mixed
*/
protected $field1;
/**
* Name of the second field to check
* @var string
*/
protected $field2;
/**
* MyCustomValidator constructor.
*
* @param array|null|\Traversable $options
*
* @throws \Exception
*/
public function __construct($options)
{
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
}
if (!array_key_exists('field1', $options) || !array_key_exists('field2', $options)) {
throw new \Exception('Options should include both fields to be defined within the form context');
}
$this->field1 = $options['field1'];
$this->field2 = $options['field2'];
parent::__construct($options);
}
/**
* Returns true if and only if $value meets the validation requirements
* If $value fails validation, then this method returns false, and
* getMessages() will return an array of messages that explain why the
* validation failed.
*
* @param mixed $value
* @param array $context
*
* @return bool
*/
public function isValid($value, $context = [])
{
$this->setValue($value);
if (empty($value) && (array_key_exists($this->field2, $context) || empty($context[$this->field2]))) {
$this->error(self::FIELDS_EMPTY);
return false;
}
return true;
}
}
那么如何使用它:
public function getInputFilterSpecification()
{
return [
'foo' => [
'validators' => [
[
'name' => MyCustomValidator::class,
'options' => [
'field1' => 'foo',
'field2' => 'bar',
]
]
]
],
'bar' => [
'validators' => [
[
'name' => MyCustomValidator::class,
'options' => [
'field1' => 'bar',
'field2' => 'foo',
]
]
]
],
];
}
对于那些不知道如何注册 MyCustomValidator 的人 - 在您的 module.config.php 中或在您的 Module.php 中使用public function getValidatorConfig()
。不要同时使用两者,它是一个或另一个:
如何在你的 module.config.php 中注册
'validators' => array(
'factories' => array(
MyCustomValidator::class => MyCustomValidatorFactory::class,
),
),
如何在你的 module.php 中注册:
/**
* Expected to return \Zend\ServiceManager\Config object or array to
* seed such an object.
* @return array|\Zend\ServiceManager\Config
*/
public function getValidatorConfig()
{
return [
'aliases' => [
'myCustomValidator' => MyCustomValidator::class,
'MyCustomValidator' => MyCustomValidator::class,
'mycustomvalidator' => MyCustomValidator::class,
],
'factories' => [
MyCustomValidator::class => MyCustomValidatorFactory::class,
],
];
}
工厂类:
class MyCustomValidatorFactory implements FactoryInterface, MutableCreationOptionsInterface
{
/**
* Options for the InputFilter
*
* @var array
*/
protected $options;
/**
* Create InputFilter
*
* @param ServiceLocatorInterface $serviceLocator
*
* @return BlockChangeOnSerialsValidator
*/
public function createService(ServiceLocatorInterface $serviceLocator)
{
return new MyCustomValidator($this->options);
}
/**
* Set creation options
*
* @param array $options
*
* @return void
*/
public function setCreationOptions(array $options)
{
$this->setOptions($options);
}
/**
* Set options
*
* @param array $options
*/
public function setOptions(array $options)
{
$this->options = $options;
}
}
请注意,我使验证器isValid()
方法非常简单,因为我不确定它是否涵盖了您的情况,但这是为了帮助您朝着正确的方向前进。但是可以进行的改进是重用 NotEmpty 验证器来检查字段是否为空。
请注意,isValid($value, $context = null)
当您调用时,表单中的上下文是 formData $form->setData($this->getRequest()->getPost())
。