我有一个Form,FormFactory和InputFilter。我想实例化一个表单并将输入过滤器分配给createService()
方法上的表单。
模块具有getFormElementConfig()
方法和getInputFilterConfig()
当我尝试从表单工厂访问$serviceManager->get('InputFilterManager')->get('Page\Form\NewsFormInputFilter')
时,我得到以下错误消息
提供的过滤器规范无效;既不是过滤器实例 也不是数组规范
模块/页/ Module.php
<?php
namespace Page;
use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module implements AutoloaderProviderInterface, ConfigProviderInterface
{
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
public function getFormElementConfig()
{
return array(
'factories' => array(
'Page\Form\NewsForm' => 'Page\Form\NewsFormFactory',
)
);
}
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__
)
)
);
}
public function getInputFilterConfig()
{
return array(
'invokables' => array(
'Page\Form\NewsFormInputFilter' => 'Page\Form\NewsFormInputFilter'
)
);
}
}
模块/页/ SRC /页/窗体/ NewsFormFactory.php
<?php
namespace Page\Form;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\MutableCreationOptionsInterface;
use Page\Form\NewsForm;
class NewsFormFactory implements FactoryInterface, MutableCreationOptionsInterface
{
protected $options;
public function setCreationOptions(array $options)
{
$this->options = $options;
}
public function createService(ServiceLocatorInterface $serviceLocator)
{
$serviceManager = $serviceLocator->getServiceLocator();
$form = new NewsForm();
$form->setTranslator($serviceManager->get('translator'));
$form->setInputFilter($serviceManager->get('InputFilterManager')->get('Page\Form\NewsFormInputFilter'));
return $form;
}
}
模块/页/ SRC /页/窗体/ NewsForm.php
<?php
namespace Page\Form;
use Zend\Form\Element;
use Zend\InputFilter;
use Zend\Form\Form;
use Zend\Form\Element\Select;
use Zend\InputFilter\InputFilterInterface;
use Zend\I18n\Translator\TranslatorAwareTrait;
class NewsForm extends Form
{
use TranslatorAwareTrait;
public function __construct($name = null)
{
parent::__construct('News');
}
public function init()
{
$category = new Select('category');
$category->setValueOptions($this->getNewsCategoryList());
$this->add($category);
}
private function getNewsCategoryList()
{
// implementation
}
}
模块/页/ SRC /页/窗体/ NewsFormInputFilter.php
<?php
namespace Page\Form;
use Zend\Filter\StringTrim;
use Zend\InputFilter\InputFilterProviderInterface;
use Zend\InputFilter\InputFilter;
use Zend\Form\Element;
class NewsFormInputFilter extends InputFilter
{
public function init()
{
$this->add(
array(
'name' => 'category',
'required' => true,
'filters' => array(
'name' => 'StringTrim'
)
)
);
}
}
根据Module Manager Listeners,getInputFilterConfig()
Module.php
我不确定我做错了什么。任何想法都是受欢迎的。
修改
根据InputFilter并解释为@Purple Hexagon我已从NewsFormInputFilter中删除了InputFilterProviderInterface实现,并仅从InputFilter
扩展还从NewsForm
中删除了$ inputFilter属性和getter方法的重复实现答案 0 :(得分:1)
您很可能遇到配置问题。我认为这一行很可能不会返回任何内容:
$serviceManager->get('InputFilterManager')->get('Page\Form\NewsFormInputFilter');
我看到您在Module.php 'Page\Form\NewsFormInputFilter'
方法中声明了getInputFilterConfig()
。但是我的代码中没有看到InputFilter
。你有那个班的文件吗?
您应该在命名空间NewsFormInputFilter
中有一个名为Page\Form
的输入过滤器类。
尝试删除getInputFilterSpecification
,不要实施InputFilterProviderInterface
。在我看来,你希望调用init
。您不需要界面和getInputFilterSpecification
方法。
确保您的模块类实现Zend\ModuleManager\Feature\InputFilterProviderInterface
。
您确定自己的文件位于Page
模块中吗?
答案 1 :(得分:1)
InputFilter类不需要实现InputFilterProviderSpecification。您还需要为每个过滤器提供带有数组的过滤器数组部分(如下所示)。您在过滤器部分中有名称键而不是包含在NewsFormInputFilter :: init中的数组中以下代码适用于您的实现
<?php
namespace Page\Form;
use Zend\Filter\StringTrim;
use Zend\InputFilter\InputFilter;
use Zend\Form\Element;
class NewsFormInputFilter extends InputFilter
{
public function init()
{
$this->add(
array(
'name' => 'name',
'required' => true,
'filters' => array(
array(
'name' => 'StringTrim'
)
)
)
);
}
}
我已经测试了上面的代码,除了NewsForm :: getNewsCategoryList没有实现之外,它工作得很好。
还有一些我不确定你为什么要这样做的事情:
1:在NewsForm类中,您重写setInputFilter方法并再次定义该属性。这一切都是在Zend \ Form \ Form类中为您完成的,您将对其进行扩展。
2:似乎很奇怪您在表单中定义了serviceLocator的getter和setter。他们没有被使用,无论如何都是一个非常大的代码味道。你有一个依赖注入工厂。猜猜你最终可能会在getNewsCategoryList中使用,但最好使用构造函数/ setter注入依赖项。
3:我不建议直接在表单中实例化Element类。如果你总是使用规范,那么从长远来看它会更好。像:
public function init()
{
$this->add(
array(
'name' => 'title',
'type' => 'Zend\\Form\\Element\\Select',
'options' => array(
'empty_option' => 'Please Select A Value...',
'label' => 'Title',
'value_options' => $this->getNewsCategoryList()
),
'attributes' => array(
'required' => 'required',
)
)
)
}