У меня есть одна вещь, которую я не знаю, как решить хорошо: я пытаюсь использовать ZF2 InputFilterManager
для получения моих входных фильтров, которые используют некоторые собственные валидаторы.
Я добавил валидаторы в конфигурацию менеджера сервисов, чтобы они могли быть получены с помощью InputFilterManager и вставлены по ссылке на ключевое слово в определении InputFilter. это прекрасно работает, поскольку валидаторам не нужно ничего вводить или какие-либо объекты, доступные из ServiceLocator.
Но одному валидатору нужно вставить массив для проверки in_array внутри. это не возможно внедрить этот массив в фабрику валидатора, потому что это зависит от бизнес-логики, которая выполняется до InputFilter isValid()
звонок происходит.
Без использования менеджера сервисов я бы внедрил этот массив в конструктор валидатора и инициализировал его после вызова бизнес-логики. Таким образом, вопрос: если я удаляю инъекцию с помощью конструктора, чтобы использовать InputFilterManager
Мне нужно будет ввести его позже с помощью: $inputFilter->get('element')->getValidatorChain()->plugin(Validator\ArrayCheck::class)->setPossibleValues($array)
— это путь?
Мне очень нравится иметь необходимые зависимости, вводимые в классы с помощью конструктора, и мне кажется немного грязным переписывать валидатор, чтобы полагаться на инъекцию сеттера, и добавлять проверку, чтобы убедиться, что сеттер использовался перед запуском isValid()
логика.
Некоторый код, чтобы объяснить мою озабоченность:
return [
'validators' => [
'invokables' => [
Validator\ArrayCheck::class => Validator\ArrayCheck::class
]
],
'input_filters' => [
'invokables' => [
InputFilter\Foo::class => InputFilter\Foo::class,
],
],
];
final class Process extends InputFilter
{
public function init()
{
$this->add(
[
'name' => 'foo',
'required' => true,
'allow_empty' => false,
'validators' => [
['name' => Validator\ArrayCheck::class]
],
]
);
}
}
class ArrayCheck extends AbstractValidator
{
/**
* @param array $possibleValues
* @param array|Traversable $options
*/
public function __construct(array $possibleValues = [], $options = null)
{
parent::__construct($options);
$this->possibleValues = $possibleValues;
}
/**
* @param array $possibleValues
*/
public function setPossibleValues(array $possibleValues)
{
$this->possibleValues = $possibleValues;
}
...
}
Есть мнения по этому поводу?
Я думаю, вы должны взглянуть на Callback
фильтр и Callback
классы валидатора.
Фильтр обратного вызова запускает функцию или метод класса при фильтрации вашего значения. Вы можете прочитать на Callback
класс фильтра здесь, в документации ZF2. Вы можете найти класс здесь на GitHUB.
Валидатор обратного вызова запускает функцию или метод класса при проверке вашего значения. Вы можете прочитать на Callback
класс валидатора здесь, в документации ZF2. Вы можете найти класс здесь на GitHUB.
Они оба используют функция PHP call_user_func_array
внутренне.
Допустим, вам нужно отфильтровать, используя dependent business logic
в классе My\Filter\Dependency
и ваш метод называется filterLogic
и / или вам нужно подтвердить, используя ваш dependent business logic
в классе My\Validator\Dependency
и ваш метод называется validateLogic
, Вы делаете это так:
$this->add([
'name' => 'foo',
'required' => true,
'allow_empty' => false,
`filters` => [
[
'name' => \Zend\Filter\Callback::class
'callback' => [
'My\Filter\Dependency::filterLogic'
],
'options' => [
'argument1' => 'param1', //optional
'argument2' => 'param2' //optional
]
]
],
'validators' => [
[
'name' => \Zend\Validator\Callback::class
'callback' => [
'My\Validator\Dependency::validateLogic'
],
'options' => [
'argument1' => 'param1', //optional
'argument2' => 'param2' //optional
]
]
],
]
]);
Оба Callback
занятия будут звонить call_user_func_array
с вашими ценностями для callback
а также options
в качестве аргументов.
Если вам нужны значения из вашего input-фильтра в функциях обратного вызова, вам нужно будет получить их из вашего InputFilter
экземпляр вручную ($inputFilter->getRawValues();
) и передать их функции в качестве аргумента.
Если это не решает вашу проблему, попробуйте лучше объяснить, что вам нужно. Я могу попытаться придумать что-то еще: D
Других решений пока нет …