AnnotationClassLoader 的 configureRoute() 的实现

Implementation for configureRoute() of AnnotationClassLoader

在我的 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\AnnotationClassLoaderclass。它只实现了一种方法:

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

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

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

这个表达式让你得到类似的东西:

MyPluginBundle\Controller\DefaultController::indexAction

显然,格式 MyPluginBundle:Default:index 只是一个快捷方式,不是必需的。

但这仍然悬而未决:是否有更简单的(例如内置)方法来实现此目的?