在ExceptionListener中调用容器

时间:2018-02-08 15:01:42

标签: symfony symfony-2.1 symfony-2.3 monolog

我正在使用Symfony,我已经创建了自定义的ExceptionListener来处理错误。

class ExceptionListener
{
    protected $templating;
    protected $kernel;

    public function __construct(EngineInterface $templating, $kernel)
    {
        $this->templating = $templating;
        $this->kernel = $kernel;
    }

    public function onKernelException(GetResponseForExceptionEvent $event)
    {

            // exception object
            $exception = $event->getException();

            // new Response object
            $response = new Response();




          $response->setContent(
            // create you custom template AcmeFooBundle:Exception:exception.html.twig
                $this->templating->render(
                    'Exception/exception.html.twig',
                    array('exception' => $exception)
                )
            );

            // HttpExceptionInterface is a special type of exception
            // that holds status code and header details
            if ($exception instanceof HttpExceptionInterface) {
                $response->setStatusCode($exception->getStatusCode());
                $response->headers->replace($exception->getHeaders());

            } else {
                 $this->container->get('monolog.logger.db')->info('something happened 34', [
        'foo' => 'bar'
    ]);

                $response->setStatusCode(500);

            }
            if($exception instanceof FatalThrowableError){
                return  $this->templating->render(
                    'Exception/exception.html.twig'

                );

            }

            // set the new $response object to the $event
            $event->setResponse($response);

    }
}

并在服务中

 kernel.listener.acme_foo_exception_listener:
        class: AppBundle\Listener\ExceptionListener
        arguments: [@templating, @kernel]
        tags:
            - { name: kernel.event_listener, event: kernel.exception, method: onKernelException }

我的目标是当symfony引发异常时我需要在数据库中记录错误,所以我已经根据下面的链接创建了Logger事件,并且当我在控制器中调用时它工作正常但是当我在里面调用时这个事件不起作用的ExceptionListener。

我收到了以下错误

  

注意:未定义的属性:   AppBundle \ Listener \ ExceptionListener :: $ container in

任何人都可以帮助我如何在Listener中传递容器

2 个答案:

答案 0 :(得分:1)

与错误一样,您正在尝试访问不存在的属性:

 $this->container->get('monolog.logger.db')->info('something happened 34', [
    'foo' => 'bar'
]);

永远不会声明或分配容器属性。如果要访问日志记录服务,请将其注入服务定义中,就像使用模板和内核服务一样。 更新了服务定义:

    kernel.listener.acme_foo_exception_listener:
        class: AppBundle\Listener\ExceptionListener
        arguments: [@templating, @kernel, @monolog.logger.db]
        tags:
        - { name: kernel.event_listener, event: kernel.exception, method: onKernelException }

并更新您的类构造函数以接受日志服务作为第三个参数。

答案 1 :(得分:1)

正如geoforce所说,您的服务并不了解容器。通过更改服务参数快速解决此问题:

arguments: [@templating, @container]

将侦听器构造函数更改为:

public function __construct(EngineInterface $templating, ContainerInterface $container)
{
    $this->container = $container;
    // ...

这应该可行,但是注入整个容器是相当大的,应该以不同的方式完成。注入你需要的东西:

arguments: [@templating, '@monolog.logger.db']

你的构造函数:

public function __construct(EngineInterface $templating, 
LoggerInterface $logger)
{
    $this->logger = $logger;
    // ...

使用$this->logger->info(...)

进行记录

由于您已经说过您是Symfony的新手,我强烈建议您阅读DI组件(http://symfony.com/doc/current/components/dependency_injection.html)docs。了解DI的作用及其工作方式对于使用Symfony等MVC框架是必须的。