在 ExceptionListener 内部调用容器

Call container inside ExceptionListener

我正在使用 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 事件 link 当我在控制器中调用时它工作正常但是这个事件不起作用当我在 ExceptionListener 内部调用时。

我收到以下错误

Notice: Undefined property: AppBundle\Listener\ExceptionListener::$container in

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

如错误所述,您正在尝试访问不存在的 属性:

 $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 }

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

正如 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) 文档。了解 DI 的作用及其工作原理是使用 Symfony 等 MVC 框架所必需的。