Php 过滤器中的Zend Framework 2依赖项注入

Php 过滤器中的Zend Framework 2依赖项注入,php,dependency-injection,zend-framework2,Php,Dependency Injection,Zend Framework2,我现在正试图在ZF2中实现我自己的过滤器 然而,我遇到了一个问题,我找不到足够清晰的文档 我的过滤器需要同时获取选项数组(在我的例子中,它包含宽度和高度字段)和服务定位器实例 但是,我无法让它接收WebinoImageThumb类实例 下面是筛选代码(这里,$this->serviceLocator始终保持空值,这就是问题所在): 您案例中的输入筛选器未由服务管理器实例化,这就是为什么其中没有service locator实例的原因。要解决此问题,可以手动创建筛选器对象,以便访问service

我现在正试图在ZF2中实现我自己的过滤器

然而,我遇到了一个问题,我找不到足够清晰的文档

我的过滤器需要同时获取选项数组(在我的例子中,它包含
宽度
高度
字段)和服务定位器实例

但是,我无法让它接收
WebinoImageThumb
类实例

下面是筛选代码(这里,
$this->serviceLocator
始终保持空值,这就是问题所在):


您案例中的输入筛选器未由服务管理器实例化,这就是为什么其中没有service locator实例的原因。要解决此问题,可以手动创建筛选器对象,以便访问service manager。然后,可以将其附加到表单中输入过滤器的过滤器链

更新 我找到了解决你问题的办法。您可以保持代码的原样。如果您从控制器创建表单,那么下面的代码片段将适合您(已测试)

事实证明,过滤器链使用插件管理器管理其过滤器。根据定义,插件管理器不保留任何服务定位器,因此您可以像我在上面的示例中所做的那样随意设置一个。在筛选代码中,您可以访问主服务定位器,如下所示:

$mainServiceLocator = $this->getServiceLocator()->getServiceLocator();

注入服务定位器是一种糟糕的设计策略;更好的方法是注入类所需的
WebinoImageThumb
“服务”

首先删除
ServiceLocator
引用,并将新服务添加为构造函数参数

namespace MyModule\Filter;

class FitImage extends AbstractFilter
{    
    protected $thumbnailService;

    protected $height;

    protected $width;

    // Type hinting on 'ThumbnailServiceInterface' would mean you can swap
    // out the 'service' with another at a later date
    public function __construct(ThumbnailServiceInterface $thumbnailService, $height = 100, $width = 100)
    {
        $this->thumbnailService = $thumbnailService;
        $this->height = $height;
        $this->width = $width;
    }

    public function filter($value)
    {
        $thumb = $this->thumbnailService->create($value);
        $thumb->resize($this->height, $this->width);
        $thumb->save($value);

        return $value;
    }

    public function setHeight($height) {
       $this->height = intval($height);
    }

    public function setWidth($width) {
        $this->width = intval($width);
    }

}
然后创建一个服务工厂来创建过滤器

namespace MyModule\Filter;

use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class FitImageFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        // $serviceLocator here is the 'filter plugin manager'
        $serviceManager = $serviceLocator->getServiceLocator();
        $options = $this->getOptions($serviceLocator);

        return new FitImage(
            $serviceManager->get('WebinoImageThumb'),
            $options['height'],
            $options['width']
        );
    }

    protected function getOptions(ServiceLocatorInterface $serviceLocator)
    {
        // This could be loaded from config
        return array('height' => 100, 'width' => 100);
    }
}
最后,添加对module config或
module.php的引用,如下所示

public function getFilterConfig()
{
    return array(
        'factories' => array(
            'MyModule\Filter\FitImage' => 'MyModule\Filter\FitImageFactory',
        ),
    );
}

作为不知道具体项目的旁注,您可能想考虑将缩略图创建从“筛选器”移动到单独的服务中。过滤器用于过滤/修改给定的输入

$value
,并返回格式化的值。

是否有方法不手动创建过滤器对象?我有很多其他的过滤器都是用同样的方法创建的,我很想把它们都放在一起,就像现在一样。另外,我是ZF2的新手,如果您能发布尽可能多的示例代码,我将不胜感激。非常感谢。好的,我为你的问题找到了一个很好的解决方案。我已经更新了上面的答案。AlexP,谢谢你的回答!能否请您更新代码,以显示如何从输入筛选器规范(位于AuthorForm中)获取选项?@Maksym有一个
setOptions
方法,该方法实际检查您传入的选项的“setter”方法。因此,当您将过滤器附加到表单时,您应该能够添加一个
setWidth()
setHeight()
,并且能够传入'height'和'width'作为选项-我在我的示例中对此进行了更新,并使
\u构造函数的
$height
$width
具有默认值,而不是被要求。
namespace MyModule\Filter;

class FitImage extends AbstractFilter
{    
    protected $thumbnailService;

    protected $height;

    protected $width;

    // Type hinting on 'ThumbnailServiceInterface' would mean you can swap
    // out the 'service' with another at a later date
    public function __construct(ThumbnailServiceInterface $thumbnailService, $height = 100, $width = 100)
    {
        $this->thumbnailService = $thumbnailService;
        $this->height = $height;
        $this->width = $width;
    }

    public function filter($value)
    {
        $thumb = $this->thumbnailService->create($value);
        $thumb->resize($this->height, $this->width);
        $thumb->save($value);

        return $value;
    }

    public function setHeight($height) {
       $this->height = intval($height);
    }

    public function setWidth($width) {
        $this->width = intval($width);
    }

}
namespace MyModule\Filter;

use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class FitImageFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        // $serviceLocator here is the 'filter plugin manager'
        $serviceManager = $serviceLocator->getServiceLocator();
        $options = $this->getOptions($serviceLocator);

        return new FitImage(
            $serviceManager->get('WebinoImageThumb'),
            $options['height'],
            $options['width']
        );
    }

    protected function getOptions(ServiceLocatorInterface $serviceLocator)
    {
        // This could be loaded from config
        return array('height' => 100, 'width' => 100);
    }
}
public function getFilterConfig()
{
    return array(
        'factories' => array(
            'MyModule\Filter\FitImage' => 'MyModule\Filter\FitImageFactory',
        ),
    );
}