如何修复 ZF2 中的“在干草堆中找不到输入"? [英] How to fix 'The input was not found in the haystack' in ZF2?

查看:36
本文介绍了如何修复 ZF2 中的“在干草堆中找不到输入"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的代码中有一个无法解决的问题.我正在使用 Zend 框架 2.4 并且我写了一个表单,但是一旦我验证它,我就收到错误在大海捞针中找不到输入.这是我收到错误的 3 个输入:

I have an issue in my code which I can't resolve. I'm using Zend framework 2.4 and I wrote a form but as soon as I validate it, I got the error The input was not found in the haystack. This are the 3 input where I got the error:

 $this->add(array(
        'name' => 'ACTIVITE1',
        'type' => 'Zend\Form\Element\Select',
        'required' => 'required',
        'options' => array(
            'value_options' => array(
                'Choisir l\'activité'
            ),
            'disable_inarray_validator' => false,
        ),
        'attributes' => array(
            'class' => 'form-control',
            'id' => 'select-session1'
        )
    ));

    $this->add(array(
        'name' => 'ACTIVITE2',
        'type' => 'Zend\Form\Element\Select',
        'required' => 'required',
        'options' => array(
            'value_options' => array(
                'Choisir l\'activité'
            )
        ),
        'disable_inarray_validator' => false,
        'attributes' => array(
            'class' => 'form-control',
            'id' => 'select-session2'
        )
    ));

    $this->add(array(
        'name' => 'ACTIVITE3',
        'type' => 'Zend\Form\Element\Select',
        'required' => 'required',
        'options' => array(
            'value_options' => array(
                'Choisir l\'activité'
            )
        ),
        'disable_inarray_validator' => false,
        'attributes' => array(
            'class' => 'form-control',
            'id' => 'select-session3'
        )
    ));

我以其他形式看到我应该把 'disable_inarray_validator' =>false 但这也不起作用.

I saw in other form that I should put 'disable_inarray_validator' => false but this doesn't work too.

推荐答案

当然不行.

该消息来自 \Zend\Validator\InArray,本质上,它的意思是:您的用户正在对您的选择进行一些操作,请注意".

That message comes from the \Zend\Validator\InArray and essentially, it means: "your user is doing something hacky with your select, pay attention".

一个例子是 Select Preferred Fruit 有两个选项,如Banana"和Ananas",但用户破解"选择并向服务器发送值Audi".InArray 验证器非常重要,不应禁用(好吧,仅在少数例外情况下..).

An exemple would be a Select Preferred fruit with two options, like "Banana" and "Ananas", but the user "hacks" the select and sends to the server the value "Audi". The InArray validator is really important and shouldn't be disabled (well, only in a few exceptions..).

现在,为什么会出现此错误?答案是......你没有告诉选择选项是什么.您创建了一个 Select,但您没有指定它的选项是什么.您将标签/占位符放在选项的位置.正确的选择是:

Now, why are you getting this error? The answer is... You didn't told what are the select options. You created a Select, but you didn't specified what are its options. You put the label/placeholder at the place of the options. A correct Select would be:

$this->add(array(
    'name' => 'ACTIVITE1',
    'type' => 'Zend\Form\Element\Select',
    'required' => 'required',
    'options' => array(
        'value_options' => array(
            1 => 'Fitness',
            2 => 'Parcour',
            3 => 'Velo',
            4 => 'Tapis roulant',
            // ... and so on
        )
    ),
    'attributes' => array(
        'class' => 'form-control',
        'id' => 'select-session1',
        'placeholder' => "Choisir l'activité"
    )
));

什么是奇怪"是你在一个空的选择中填充一些东西,然后我的问题是:为什么?

What is "weird" is the fact that you are filling something in an empty select, and my question then is: why?

选择(通常)用于预定义的值列表.如果您想让您的用户填写自定义文本,那么您应该考虑创建一个带有自动完成选项的 Text 字段.

Selects are (typically) there for a predefined list of values. If you want to allow your users to fill a custom text, then you should consider to create a Text field with the autocomplete option.

如果您想创建一个包含来自数据库的选项列表的选择,路线会稍微复杂一些,但是一旦您学会了如何去做,它就会变得更容易.

If you want to create a select with a list of options that come from the database, the route is a bit more complex, but once you've learned how to do it, it will become way easier.

请注意:这不是复制和粘贴解决方案".由于我无法访问您的代码,因此我编造了名称(类、命名空间、方法、变量)只是为了创建一个完整的示例 :)

PAY ATTENTION: this will not be a "copy&paste solution". Since I'm not having access to your code, I'm making up names (classes, namespaces, methods, variables) just to create a complete example :)

首先,您必须创建一个自定义元素.在这种情况下,它将是一个自定义选择:

First off, you must create a custom element. In this case, it will be a custom select:

namespace Yournamespace;

use Zend\Form\Element\Select;
use Yournamespace\ActivityMapper;

class ActivitySelect extends Select {

    protected $activityMapper;

    public function __construct(ActivityMapper $activityMapper, $name = null, $options = []) {
        parent::__construct($name, $options);
        $this->activityMapper = $activityMapper;
    }

    public function init() {
        $valueOptions = [];
        foreach ($this->activityMapper->fetchAll() as $activity) {
            $valueOptions[$activity->getActivityId()] = $activity->getActivityName();
        }
        $this->setValueOptions($valueOptions);
    }

}

这里真正重要的是您必须在 init 方法中实例化您的元素(选项、类等..).

What is really important here is that you must instantiate your element (options, classes, and so on..) inside init method.

因为这个元素有一个依赖(ActivityMapper),你必须为这个元素创建一个工厂:

Since this element has a dependency (ActivityMapper), you'll have to create a factory for this element:

namespace Yournamespace;

use Zend\ServiceManager\Factory\FactoryInterface;
use \Interop\Container\ContainerInterface;

class ActivitySelectFactory implements FactoryInterface {

    public function __invoke(ContainerInterface $container, $requestedName, array $options = null): object {
        $activityMapper = $container->get(\Yournamespace\ActivityMapper::class);
        return \Yournamespace\ActivitySelect($activityMapper);
    }

}

必须在配置中添加这个工厂,更准确地说,在module.config.php里面:

This factory must be added in the configuration, more precisely, inside module.config.php:

return [
    // ...
    'form_elements' => [
        'factories' => [
            \Yournamespace\ActivitySelect::class => \Yournamespace\ActivitySelectFactory::class,
        ]
    ]
    // ...
];

现在,您也必须修改表单.所有元素都必须添加到 init 方法中,而不是在构造函数中:

Now, you must modify your form too. All elements must be added to form inside init method, and not inside the constructor:

namespace Yournamespace;

use Zend\Form\Form;
use Zend\InputFilter\InputFilterProviderInterface;

class ActivityForm extends Form implements InputFilterProviderInterface {

    public function init() {
        parent::init();

        // ...
        $this->add([
            'name' => 'ACTIVITE1',
            'type' => \Yournamespace\ActivitySelect::class,
            'attributes' => [
                'class' => 'form-control',
                'id' => 'select-session1',
                'required' => true, // This will work only clientside, don't forget the inputfilter!
                'placeholder' => 'Choisir l\'activité',
            ],
            'options' => [
                'label' => 'Choisir l\'activité',
            ]
        ]);
        // ...

    }

    public function getInputFilterSpecification() {
        // ...
        $inputFilter[] = [
            'name' => 'ACTIVITE1',
            'required' => true
        ];
        // ...
        return $inputFilter;
    }

}

最后,您还必须修改您的控制器,因为您需要从 FormElementManager 中检索表单:

Finally, you'll have to modify your controller too, because you need to retrieve the form from the FormElementManager:

namespace Yournamespace;

use Zend\Form\FormElementManager;

class YourController extends AbstractActionController {
    private $formManager;

    public function __construct(FormElementManager $formManager) {
        $this->formManager = $formManager;
    }

    public function choisirActiviteAction(){
        // ...
        $form = $this->formManager->get(\Yournamespace\ActivityForm::class);
        // ...
    }
}

下一步是为 $formManager 创建一个控制器插件,而不是将其作为每个控制器的依赖项,但这是一个不同的问题..

A next nice step would be to create a controller plugin for the $formManager, instead of making it as a dependency of each controller, but this is a different problem..

这篇关于如何修复 ZF2 中的“在干草堆中找不到输入"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆