Реализация для configureRoute() 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
учебный класс. Он реализует только один метод:
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 ответ
Хорошо, действительно простое решение (которое я нашел методом проб и ошибок):
$route->setDefault('_controller', $method->class.'::'.$method->name);
Это выражение дает вам что-то вроде:
MyPluginBundle\Controller\DefaultController::indexAction
Соответственно, формат MyPluginBundle:Default:index
это просто ярлык и не требуется.
Но это все еще оставляет вопрос открытым: есть ли более простой (например, встроенный) способ добиться этого?