Как зарегистрировать маршруты из .yaml и через аннотации с помощью компонента маршрутизации Symfony в приложении PHP - PullRequest
0 голосов
/ 30 сентября 2019

У меня есть простое приложение php, и я хочу использовать компонент маршрутизации Symfony для создания маршрутов как с помощью аннотаций, так и yaml

Я могу создавать маршруты в yaml. Работа с комментированной частью при определении маршрутов в yaml

    foos_route:
    path:     /foos
    defaults: { _controller: 'App\Controller\MainController', _method: 'index3'}

#   foo_placeholder_route:
#   path:     /foo/{id}
#   defaults: { _controller: 'App\Controller\MainController', _method: 'index2'}
#   requirements:
#      id: '[0-9]+'

Контроллерная часть с аннотациями и 1 метод для yaml

class MainController
{
    /**
     * @Route("/foo", name="foo_route")
     */
    public static function index()
    {
        echo 'aaaaa';
    }

    /**
     * @Route("/foo/{id}", name="foo_route2")
     */
    public static function index2()
    {
        echo 'bbbbb';
    }

    public static function index3()
    {
        echo 'cccccc';
    }
}

Index.php часть

try
{
    $fileLocator = new FileLocator([__DIR__. '/config/']);

    // Init RequestContext object
    $requestContext = new RequestContext();
    $requestContext->fromRequest(Request::createFromGlobals());

    /*WORKING YAML PART*/
    $router = new Router(
        new YamlFileLoader($fileLocator),
        'routes.yaml',
        [],
        $requestContext
    );

    // Find the current route
    $parameters = $router->match($requestContext->getPathInfo());
    $controller = new $parameters['_controller'];
    echo $controller->{$parameters['_method']}();
    /*WORKING YAML PART*/

    /*WORK ANNOTATION PART*/
    $loader = new AnnotationDirectoryLoader(
        $fileLocator,
        new AnnotatedRouteControllerLoader(
            new AnnotationReader()
        )
    );

    $routes = $loader->load(__DIR__.'/app/Controller/');

    // Init UrlMatcher object
    $matcher = new UrlMatcher($routes, $requestContext);

    // Find the current route
    $parameters = $matcher->match($requestContext->getPathInfo());
    call_user_func($parameters['_controller']);
    /*WORKING ANNOTATIONS PART*/
}
catch (ResourceNotFoundException $e)
{
    echo $e->getMessage();
}

Я следовал Routing Component документация работает, но я не могу понять, почему эти две части можно определить как из двухсторонних аннотаций, так и из .yaml

РЕШЕНИЕ: я не уверен, что этоэто лучшее решение, но я использовал loaderResolver

$fileLocator = new FileLocator([__DIR__. '/config/']);

$yamlLoader = new YamlFileLoader($fileLocator);
$annotationsLoader = new AnnotationDirectoryLoader(
    $fileLocator,
    new AnnotatedRouteControllerLoader(
        new AnnotationReader()
    )
);

$loaderResolver = new LoaderResolver([$yamlLoader, $annotationsLoader]);
$delegatingLoader = new DelegatingLoader($loaderResolver);

$routes = new RouteCollection();
$routes->addCollection($delegatingLoader->load(__DIR__ . '/config/routes.yaml'));

$matcher = new UrlMatcher($routes, $requestContext);

1 Ответ

0 голосов
/ 01 октября 2019

UrlMatcher (используется в обоих случаях) выдает исключения, когда маршрут не найден. Тогда вам просто нужно перехватить их исключения, а затем перейти к следующему методу, если первый не работает:

try
{
    /*WORKING YAML PART*/
    //...
    /*WORKING YAML PART*/
} catch (ResourceNotFoundException | NoConfigurationException $e)
    try {
        /*WORKING ANNOTATION PART*/
        //...
        /*WORKING ANNOTATIONS PART*/
    } catch (ResourceNotFoundException $e) {
        echo $e->getMessage();
    }
}

https://github.com/symfony/routing/blob/master/Matcher/UrlMatcherInterface.php#L36

Должно работать.

...