I'm in the process of upgrading Symfony from 3.4 to 4.3 and I have a situation in which every route is matched with controller and method correctly, but then the request reaches RedirectableCompiledUrlMatcher
and replaces correct parameters with
_controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction
That triggers all sorts of other stuff like invoking param converters, hitting firewalls, and other routing related stuff which it isn't supposed to because the matched route isn't correct.
Debugging 3.4 project continues without replacing the correct parameters.
My question is whether this is now the correct request flow (i.e. every route has to pass urlRedirectAction) and I need to configure other stuff or is there any way I can avoid invoking, I guess, RedirectableCompiledUrlMatcher
?
Is it possible that this happens because RedirectableUrlMatcher
is the default matcher for \Symfony\Component\Routing\Router
and how come it is the default one? Any chance to replace that with ordinary UrlMatcher
like it is in the 3.4?
It's exactly this line vendor/symfony/routing/Matcher/Dumper/CompiledUrlMatcherTrait.php:63
where I have $ret
matched correctly to my controller and $this->redirect()
is being called which replaces my controller with Symfony RedirectController.
Trait is part of RedirectableCompiledUrlMatcher
class
Symfony 4 changed the routing so that routes with a trailing slash are considered equivalent to routes without one for GET and HEAD requests (cf. https://symfony.com/doc/4.3/routing.html#redirecting-urls-with-trailing-slashes).
If you have route definitions for both versions, the first one will be matched. The RedirectableUrlMatcherInterface will create a redirect to this route if you use it the other way.
# routes.yaml
foo:
path: /foo
controller: App\Controller\FooController::fooAction
foo_trail:
path: /foo/
controller: App\Controller\FooController::fooAction
GET /foo/
will redirect to GET /foo
, GET /foo
will match normally.
# routes.yaml
foo_trail:
path: /foo/
controller: App\Controller\FooController::fooAction
foo:
path: /foo
controller: App\Controller\FooController::fooAction
GET /foo
will redirect to GET /foo/
, GET /foo/
will match normally.
This redirect for the missing/additional trailing slash is what line 63 in CompiledUrlMatcherTrait does (i.e. GET /foo/
in example 1). If the route can be matched exactly (i.e. GET /foo
in example 1), this redirect should not be reached and the matcher should return in line 39.
So for your specific routing configuration, the questions are:
/foo
and /foo/
being different? That won't be possible with the default matcher anymore (for GET or HEAD requests)./foo
with /foo/
or vice versa? This shouldn't be a problem, but causes a redirect that might cause problems somewhere else.If your problem remains, please provide a relevant excerpt of your routing config with an example of requested and redirected URL.