9

最近 Symfony2 でプロジェクトを開始しましたが、コードの冗長性を避けるために、すべてのアクションの前後にいくつかのメソッドを実行する必要があります (Zend Framework の preDispatch/postDispatch や Symfony1 の PreExecute/PostExecute など)。

すべてのコントローラーが継承される基本クラスを作成し、イベントリスナーを登録して、要求されたアクションを実行する前にコントローラーの preExecute() メソッドを実行しましたが、ここから大量のドキュメントと質問を読んだ後でも、postExecute を実行する方法が見つかりません。 ().

Foo/BarBundle/Controller/BaseController.php:

class BaseController extends Controller {
  protected $_user;
  protected $_em;

  public function preExecute() {
    $user = $this->get('security.context')->getToken()->getUser();
    $this->_user = $user instanceof User ? $user : null;
    $this->_em = $this->getDoctrine()->getEntityManager();
  }

  public function postExecute() {
    $this->_em->flush();
  }
}

Foo/BarBundle/Controller/FooController.php:

class FooController extends BaseController {
  public function indexAction() {
    $this->_user->setName('Eric');
    $this->_em->persist($this->_user);
  }
}

Foo/BarBundle/EventListener/PreExecute.php:

class PreExecute {
  public function onKernelController(FilterControllerEvent $event) {
    if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) {
      $controllers = $event->getController();
      if (is_array($controllers)) {
        $controller = $controllers[0];

        if (is_object($controller) && method_exists($controller, 'preExecute')) {
          $controller->preExecute();
        }
      }
    }
  }
}
4

1 に答える 1

6

ここでこれについての議論があり、schmittjohによるこの特定の例はあなたを正しい方向に導くかもしれません。

<?php

class Listener
{
    public function onKernelController($event)
    {
        $currentController = $event->getController();
        $newController = function() use ($currentController) {
            // pre-execute
            $rs = call_user_func_array($currentController, func_get_args());
            // post-execute

            return $rs;
        };
        $event->setController($newController);
    }
}
于 2012-06-22T20:55:49.640 に答える