Laminas Fieldset 具有静态 InputFilterSpecification

Laminas Fieldset has static InputFilterSpecification

我有一个 Fieldset,其中 class 个成员用于 inputFilterSpecification:

class FileFieldset extends Fieldset implements InputFilterProviderInterface
{

    protected $mimeTypes = ['image/jpg', 'image/png', 'application/pdf'];
    protected $fileSizeMin = 0;
    protected $fileSizeMax = 1;

    public function setMimeTypes(array $mimeTypes): void
    {
        $this->mimeTypes = $mimeTypes;
    }

    public function setFileSizeMin($fileSizeMin): void
    {
        $this->fileSizeMin = $fileSizeMin;
    }
    public function setFileSizeMax($fileSizeMax): void
    {
        $this->fileSizeMax = $fileSizeMax;
    }

    public function init()
    {
        $this->add([
            'name' => 'file_file',
            'type' => File::class,
            'options' => [
                'label' => 'Datei',
            ],
        ]);
    }

    public function getInputFilterSpecification()
    {
        $filter = [];

        $filter['file_file'] = [
            'required' => true,
            'filters' => [
            ],
            'validators' => [
                [
                    'name' => MimeType::class,
                    'break_chain_on_failure' => true,
                    'options' => [
                        'enableHeaderCheck' => true,
                        'disableMagicFile' => true,
                        'magicFile' => null,
                        'mimeType' => $this->mimeTypes,
                    ]
                ],
                [
                    'name' => Size::class,
                    'options' => [
                        'min'           => $this->fileSizeMin,
                        'max'           => $this->fileSizeMax,
                        'useByteString' => true,
                    ],
                ],
            ],
        ];

        return $filter;
    }
}

这是我的表单,我在其中集成了字段集:

class FileForm extends AbstractForm implements InputFilterProviderInterface
{
    protected $fileFieldset;

    public function setFileFieldset(FileFieldset $fileFieldset): void
    {
        $this->fileFieldset = $fileFieldset;
    }

    public function init()
    {
        $this->add([
            'type' => FileFieldset::class,
            'options' => [
                'use_as_base_fieldset' => true,
            ],
        ]);

        $this->add([
            'type' => 'submit',
            'name' => 'submit',
            'attributes' => [
                'value' => 'los',
            ],
        ]);
    }

    public function getInputFilterSpecification()
    {
        return $this->fileFieldset->getInputFilterSpecification();
    }
}

如果我在控制器中调试我的表单,我会看到我在工厂中设置的正确值:

无论我在哪里调试,我总是看到预期的值。

为什么要用laminas的初始值?为什么初始值仍然存在?

[+++编辑+++]

有趣:我在函数 FileFieldset()->getInputFilterSpecification() 中查看 Fieldset 的对象 ID。这个函数被调用了三次。前两次具有预期值和相同的对象 ID。第三次,对象ID不同,值为初始值。

为什么不是单例?

为什么有一个 FileFieldset 实例不是用工厂创建的?

FileFieldsetFactory:

class FileFieldsetFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        $fieldset = new FileFieldset();
        $config = $container->get('config')['my_files'];
        $fieldset->setFileSizeMin($config['files_size_min']);
        $fieldset->setFileSizeMax($config['files_size_max']);
        $fieldset->setMimeTypes($config['files_mimetypes']);
        $fieldset->init();
        return $fieldset;
    }
}

解决问题的两件事:

  1. 在 FileFieldset 中设置名称
    public function init()
    {
        $this->setName('file_fieldset');
  1. 在 FileForm 中添加 FileFieldset 实例,而不是 $this->add(['type' => FileFieldset::class]);
$this->add($this->fileFieldset);

因此对象 ID 始终相同,并且值与预期一致。