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\AnnotationClassLoader
class。它只实现了一种方法:
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
只是一个快捷方式,不是必需的。
但这仍然悬而未决:是否有更简单的(例如内置)方法来实现此目的?
在我的 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
class。它只实现了一种方法:
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
只是一个快捷方式,不是必需的。
但这仍然悬而未决:是否有更简单的(例如内置)方法来实现此目的?