AnnotationClassLoader的configureRoute()的实现

时间:2017-05-16 13:25:33

标签: symfony routes annotations symfony-3.2 symfony-cmf

在我的Symfony 3.2应用程序中,我创建了一个从Symfony\Bundle\FrameworkBundle\Routing\Router扩展的自定义路由器。

根据需要,它实现了getRouteCollection()方法:

public function getRouteCollection() {

    $locator = new FileLocator(__DIR__ . '/../Controller');

    $annotationReader = new Doctrine\Common\Annotations\AnnotationReader();
    $classLoader = new AnnotationClassLoader($annotationReader);

    $routeLoader = new Symfony\Component\Routing\Loader\AnnotationDirectoryLoader($locator, $classLoader);
    $routes = $routeLoader->load('.\\', 'annotation');

    return $routes;
}

这里使用的AnnotationClassLoader是我自己的,它扩展了抽象Symfony\Component\Routing\Loader\AnnotationClassLoader类。它只实现了一种方法:

protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, $annot) {

    $route->setDefault('_controller', '???');
    return $route;
}

我想用它来设置注释中找到的路由的默认控制器。 AnnotationReader完全可以从源代码中读取所有路由,但它根本没有设置默认控制器,这正是我在configureRoute中尝试做的事情。似乎在找到的每条路线上都会调用该函数。

现在的问题是找到合适的表达式来替换'???'最后,我需要一个结果,例如'MyPluginBundle:ControllerName:actionName'。这意味着我需要使用我拥有的信息(这是函数的四个参数)来构建该字符串,或者我采用了一种完全错误的方法,并且有一种更简单的方法来执行此操作。

$route的示例转储:

如您所见,_controller尚无默认值。

object(Symfony\Component\Routing\Route)
  private 'path' => string '/my/route' (length=9)
  private 'host' => string '' (length=0)
  private 'schemes' => 
    array (size=0)
      empty
  private 'methods' => 
    array (size=0)
      empty
  private 'defaults' => 
    array (size=0)
      empty
  private 'requirements' => 
    array (size=0)
      empty
  private 'options' => 
    array (size=1)
      'compiler_class' => string 'Symfony\Component\Routing\RouteCompiler' (length=39)
  private 'compiled' => null
  private 'condition' => string '' (length=0)

$class的示例转储:

object(ReflectionClass)
  public 'name' => string 'MyPluginBundle\Controller\DefaultController' (length=43)

$method的示例转储:

object(ReflectionMethod)[174]
  public 'name' => string 'indexAction' (length=11)
  public 'class' => string 'MyPluginBundle\Controller\DefaultController' (length=43)

$annot的示例转储:

object(Sensio\Bundle\FrameworkExtraBundle\Configuration\Route)
  protected 'service' => null
  private 'path' (Symfony\Component\Routing\Annotation\Route) => string '/my/route' (length=9)
  private 'name' (Symfony\Component\Routing\Annotation\Route) => string 'name_of_the_route' (length=17)
  private 'requirements' (Symfony\Component\Routing\Annotation\Route) => 
    array (size=0)
      empty
  private 'options' (Symfony\Component\Routing\Annotation\Route) => 
    array (size=0)
      empty
  private 'defaults' (Symfony\Component\Routing\Annotation\Route) => 
    array (size=0)
      empty
  private 'host' (Symfony\Component\Routing\Annotation\Route) => null
  private 'methods' (Symfony\Component\Routing\Annotation\Route) => 
    array (size=0)
      empty
  private 'schemes' (Symfony\Component\Routing\Annotation\Route) => 
    array (size=0)
      empty
  private 'condition' (Symfony\Component\Routing\Annotation\Route) => null

1 个答案:

答案 0 :(得分:1)

好的,真正简单的解决方案(我通过反复试验找到)是:

$route->setDefault('_controller', $method->class.'::'.$method->name);

这个表达式可以解释如下:

MyPluginBundle\Controller\DefaultController::indexAction

显然,格式MyPluginBundle:Default:index只是一种捷径,不是必需的。

但是仍然存在问题:是否有更简单(例如内置)的方法来实现这一目标?