Zend Framework 2过滤/验证内容数组

时间:2013-08-17 22:27:25

标签: php zend-framework2

如何将过滤器应用于包含数组内容的字段元素?

例如:

$this->add(
  "name" => "tags",
  "type" => "text",
  "filter" => array(
    array("name" => "StripTags"),
    array("name" => "StringTrim")
  )
);

$tags[0] = "PHP";
$tags[1] = "CSS";

如果我尝试过滤,我收到一个错误,说标量对象被排除,给定数组。

4 个答案:

答案 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 Documentationthis working example