如何将过滤器应用于包含数组内容的字段元素?
例如:
$this->add(
"name" => "tags",
"type" => "text",
"filter" => array(
array("name" => "StripTags"),
array("name" => "StringTrim")
)
);
$tags[0] = "PHP";
$tags[1] = "CSS";
如果我尝试过滤,我收到一个错误,说标量对象被排除,给定数组。
答案 0 :(得分:9)
目前这还不可能。您最好的选择是使用Callback filter并单独过滤每个项目。像这样的东西
$this->add(
"name" => "tags",
"type" => "text",
"filter" => array(
array("name" => "Callback", "options" => array(
"callback" => function($tags) {
$strip = new \Zend\Filter\StripTags();
$trim = new \Zend\Filter\StringTrim();
foreach($tags as $key => $tag) {
$tag = $strip->filter($tag);
$tag = $trim->filter($tag);
$tags[$key] = $tag;
}
return $tags;
}))
)
);
答案 1 :(得分:6)
我意识到这已经过时但您可以将输入类型指定为ArrayInput
,而InputFilter
会按预期处理它:
"name" => "tags",
"type" => "Zend\\InputFilter\\ArrayInput", // Treat this field as an array of inputs
"filter" => array(
array("name" => "StripTags"),
array("name" => "StringTrim")
)
答案 2 :(得分:4)
我已经制作了一个CollectionValidator,它将现有的验证器应用于数组中的所有项目。
我将它与Apigility一起使用:
'input_filter_specs' => [
'Api\\Contact\\Validator' => [
[
'name' => 'addresses',
'required' => false,
'filters' => [],
'validators' => [
[
'name' => 'Application\\Validator\\CollectionValidator',
'options' => ['validator' => 'Api\\Address\\Validator']
]
],
'description'=> 'List of addresses for contact'
],
[
'name' => 'birthdate',
# ...
]
],
]
我不确定你是否会在控制器中使用验证器,但可能是这样的:
new Collection(array('validator' => 'Zend\Validator\CreditCard'))
每个索引返回validation_messages
。让我们说是创建联系人的REST POST请求,它表示第二个地址在zipcode字段中包含错误。
{
"detail": "Failed Validation",
"status": 422,
"title": "Unprocessable Entity",
"type": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html",
"validation_messages": {
"addresses": {
"1": {
"zipcode": {
"notAlnum": "The input contains characters which are non alphabetic and no digits"
}
}
},
"birthdate": {
"dateInvalidDate": "The input does not appear to be a valid date"
}
}
}
收集验证器:
<?php
namespace Application\Validator;
class Collection extends \Zend\Validator\AbstractValidator implements \Zend\ServiceManager\ServiceLocatorAwareInterface {
protected $serviceLocator;
protected $em;
protected $messages;
protected $options = array(
'validator' => null
);
public function setServiceLocator(\Zend\ServiceManager\ServiceLocatorInterface $serviceLocator) {
$this->serviceLocator = $serviceLocator->getServiceLocator();
}
public function getServiceLocator() {
return $this->serviceLocator;
}
public function isValid($array) {
$inputFilterManager = $this->getServiceLocator()->get('inputfiltermanager');
$validatorName = $this->getOption('validator');
$this->messages = [];
$isvalid = true;
foreach($array as $index => $item) {
$inputFilter = $inputFilterManager->get($validatorName);
$inputFilter->setData($item);
$isvalid = $isvalid && $inputFilter->isValid($item);
foreach($inputFilter->getMessages() as $field => $errors) {
foreach($errors as $key => $string) {
$this->messages[$index][$field][$key] = $string;
}
}
}
return $isvalid;
}
public function getMessages() {
return $this->messages;
}
}
目前的限制:
答案 3 :(得分:0)
我遇到了一个非常类似的问题,并且可以使用Zend\Form\Element\Collection
解决它。
使用集合元素,我可以验证类似
的输入$post = [
[
'idUser' => 1,
'address' => 'foo street',
],
[
'idUser' => 2,
'address' => 'bar street',
],
];
有关详细说明,请查看Zend Documentation和this working example