使用插件管理器配置Zend Framework 2输入筛选器



我遵循了zf2相册的示例。我现在正在尝试集成HTML净化器。

这是模块https://github.com/juriansluiman/Soflomo-Purifier#injecting-过滤器管理器

这就是我构建输入过滤器的方式
http://framework.zend.com/manual/current/en/user-guide/forms-and-actions.html

namespace AlbumModel;
// Add these import statements
use ZendInputFilterInputFilter;
use ZendInputFilterInputFilterAwareInterface;
use ZendInputFilterInputFilterInterface;
class Album implements InputFilterAwareInterface
{
public $id;
public $artist;
public $title;
protected $inputFilter;                       // <-- Add this variable
public function exchangeArray($data)
{
$this->id     = (isset($data['id']))     ? $data['id']     : null;
$this->artist = (isset($data['artist'])) ? $data['artist'] : null;
$this->title  = (isset($data['title']))  ? $data['title']  : null;
}
// Add content to these methods:
public function setInputFilter(InputFilterInterface $inputFilter)
{
throw new Exception("Not used");
}
public function getInputFilter()
{
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
$inputFilter->add(array(
'name'     => 'id',
'required' => true,
'filters'  => array(
array('name' => 'Int'),
),
));
$inputFilter->add(array(
'name'     => 'artist',
'required' => true,
'filters'  => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name'    => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min'      => 1,
'max'      => 100,
),
),
),
));
$inputFilter->add(array(
'name'     => 'title',
'required' => true,
'filters'  => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name'    => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min'      => 1,
'max'      => 100,
),
),
),
));
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
}

我得到以下错误。

因此,您得到一个ServiceNotFoundException:Zend\Filter\FilterPluginManager::get无法获取或创建htmlpurifier的实例。这意味着过滤器插件管理器被懒惰地实例化,并且不知道htmlpurifier插件。

构造输入过滤器以利用此模块的正确方式是什么。非常感谢,马特

您遇到的问题正是由SoflomoPurifier文档中所述内容引起的:由于您是用new InputFilter手动实例化的,所以该实例永远不会与其他模块提供的配置连接在一起。

为了确保这种连接发生,我建议创建一个新的InputFilter子类,并将所有InputFilter::add()调用放入其init()方法中:

use ZendInputFilterInputFilter:
class AlbumInputFilter extends InputFilter
{
public function init()
{
$this->add(array(
'name'     => 'id',
'required' => true,
'filters'  => array(
array('name' => 'Int'),
),
));
$this->add(array(
'name'     => 'artist',
'required' => true,
'filters'  => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name'    => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min'      => 1,
'max'      => 100,
),
),
),
));
$this->add(array(
'name'     => 'title',
'required' => true,
'filters'  => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name'    => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min'      => 1,
'max'      => 100,
),
),
),
));
}
}

将Album模型构造函数更改为使用构造函数注入:

use ZendInputFilterInputFilterInterface;
class Album
{
// etc etc
public function __construct(InputFilterInterface $inputFilter)
{
$this->inputFilter = $inputFilter;
}
// etc etc
}

然后使用工厂注入:

// in your Module.php
public function getServiceConfig()
{
return [
'factories' => [
'AlbumFactory' => function($serviceManager) {
$inputFilterManager = $serviceManager->get('InputFilterManager');
return function() use ($inputFilterManager) {
$inputFilter = $inputFilterManager->get(AlbumInputFilter::class);
return new Album($inputFilter)
}
}
]
];
}

使用输入过滤器FQCN调用InputFilterPluginManager::get()将自动调用其构造函数,将其与其他模块连接起来,然后调用其init()方法。

因此,现在,您应该使用AlbumFactory服务创建相册,而不是使用$album = new Album,并正确注入它们的输入过滤器:

$createAlbum = $serviceManager->get('AlbumFactory');
$album = $createAlbum()

很明显,建议您将这个工厂注入到任何使用者(即控制器)中,而不是从服务管理器中提取它,并可能将匿名函数重构到一个专用的工厂类中。

最新更新