【发布时间】:2019-07-06 18:43:34
【问题描述】:
Symfony 4.2.2
为了在一个控制器中缓存所有响应,我使用了 kernel.controller 事件的事件侦听器。我的事件监听器需要一些服务和信息:
- EnityManager 接口
- 被缓存的控制器
- 内核缓存文件夹
我是这样设置的:
namespace App\Listener;
use App\Controller\DataOutputController;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
class CachedOutput{
protected $cacheFolder;
protected $em;
protected $controller;
public function __construct($cacheFolder, EntityManagerInterface $em, DataOutputController $controller )
{
$this->cacheFolder = $cacheFolder;
$this->em = $em;
$this->controller = $controller;
}
public function findCachedObject(FilterControllerEvent $event, $eventName, TraceableEventDispatcher $dispatcher
){
$params = $event->getRequest()->attributes->get('_route_params');
$fileType = $this->em->getRepository('App:FileType')->find($params->get('fileType'));
$dataSet = $this->controller->getDataSet($params->get('dataSetSearch')?:'latest', $fileType->getType());
$cacheFile = $this->cacheFolder.'/output/DS'.$dataSet->getId().'-FT'.$fileType->getId().'.html';
if (file_exists($cacheFile)){
$fh = fopen($cacheFile,'r');
return new Response(fpassthru($fh));
}
}
}
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
public: true # Allows optimizing the container by removing unused services; this also means
# fetching services directly from the container via $container->get() won't work.
# The best practice is to be explicit about your dependencies anyway.
bind:
$projectDir: '%kernel.project_dir%'
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
# controllers are imported separately to make sure services can be injected
# as action arguments even if you don't extend any base controller class
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
controller.return_cached_output:
class: App\Listener\CachedOutput
arguments:
$cacheFolder: "%kernel.cache_dir%"
tags:
- { name: kernel.event_listener, event: kernel.controller, method: findCachedObject }
但是,我仍然收到有关缓存文件夹的错误:
无法自动装配服务“App\Listener\CachedOutput”:方法“__construct()”的参数“$cacheFolder”没有类型提示,您应该明确配置其值。
我错过了什么?
更新:
曾尝试为这样的服务使用别名:
App\Listener\CachedOutput:
public: false
arguments:
$cacheFolder: "%kernel.cache_dir%"
tags:
- { name: kernel.event_listener, event: kernel.controller, method: findCachedObject }
return_cached_output:
alias: App\Listener\CachedOutput
public: true
没有成功
【问题讨论】:
-
你在项目中的监听器在哪里?
-
App/Listener/Cached Output.php
-
你在哪里声明你的监听器为服务?
-
整个 services.yaml 都在问题中
-
题外话:把你的听众变成subscriber,你就可以摆脱标签部分了。在 _defaults 部分(如 $projectDir)绑定 $cacheFolder,您可以完全摆脱手动服务定义。
标签: symfony