【问题标题】:Overriding Symfony 2 exceptions?覆盖 Symfony 2 异常?
【发布时间】:2012-09-21 03:23:58
【问题描述】:

据此文档页面:

http://symfony.com/doc/current/cookbook/controller/error_pages.html

Symfony 使用 TwigBundle 来控制异常的显示。但是,我不希望自定义显示,如文档中所述,我希望覆盖它。我正在开发一个小型 REST API,我想覆盖对我的包的 TwigBundle 调用,进行我自己的异常处理(在 REST 方面:映射正确的 HTTP 状态代码和纯文本正文响应)。

我找不到任何关于此的内容,而且手册上的参考也不是很好,特别是在内核部分。也许有人已经这样做了,可以帮助我吗?谢谢。

【问题讨论】:

    标签: php symfony


    【解决方案1】:

    您应该创建一个侦听kernel.exception 事件的侦听器。在该侦听器的onKernelException 方法中,您可以检查您的异常,例如

    关于异常监听类

      //namespace declarations
      class YourExceptionListener
      {
    
          public function onKernelException(GetResponseForExceptionEvent $event)
          {
            $exception =  $event->getException();
            if ($exception instanceof YourException) {
                //create response, set status code etc.
                $event->setResponse($response); //event will stop propagating here. Will not call other listeners.
            }
          }
      }
    

    服务声明将是

     //services.yml
     kernel.listener.yourlisener:
      class: FQCN\Of\YourExceptionListener
      tags:
        - { name: kernel.event_listener, event: kernel.exception, method: onKernelException }
    

    【讨论】:

    • 我可以将监听器放在我的包的根目录吗?
    • 在调试模式下开发工具栏分析器页面。选择左侧的事件选项卡。您将看到听众列表。检查你的听众是否在那里。
    • 我的错,我正在使用 services.xml 并忘记更改我的扩展。
    【解决方案2】:

    Bellow 是我的 AppKernel.php 的一部分,用于禁用 Symfony 对 JSON 请求的内部异常捕获,(您可以覆盖 handle 方法而不是创建第二个方法)

    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpKernel\HttpKernelInterface;
    use Symfony\Component\HttpKernel\Kernel;
    use Symfony\Component\Config\Loader\LoaderInterface;
    
    class AppKernel extends Kernel {
      public function init() {
        parent::init();
    
        if ($this->debug) {
          // workaround for nasty PHP BUG when E_STRICT errors are reported
          error_reporting(E_ALL);
        }
      }
    
      public function handleForJson(Request $request,
                                    $type = HttpKernelInterface::MASTER_REQUEST,
                                    $catch = true
      ) {
        return parent::handle($request, $type, false);
      }
      ...
    

    【讨论】:

    • 这似乎有点骇人听闻......还有其他方式吗?
    • 用 OOP 对流扩展类是 hackish 吗?
    • 不确定您所说的“OOP 约定”是什么意思。好主意是不要覆盖框架类。 KernelEvents::EXCEPTION 在句柄响应的最开始抛出,因此您可以通过在自己的侦听器中侦听它而不是修改框架类来插入那里。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-19
    • 2012-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-17
    相关资源
    最近更新 更多