Symfony中如何通过kernel.controller实现指定测试路由重定向?
Hey there! Let's fix that redirection issue for your EnglishTest. The kernel.request event is exactly what we need here, and I'll walk you through a working EventSubscriber implementation that avoids the pitfalls you might have hit earlier.
Step 1: Create the Event Subscriber
First, let's build a subscriber that listens to the kernel.request event. This will let us check the current request's locale and route, then redirect if needed.
// src/EventSubscriber/EnglishTestRedirectionSubscriber.php namespace App\EventSubscriber; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; class EnglishTestRedirectionSubscriber implements EventSubscriberInterface { private $urlGenerator; // Inject the URL generator to build the correct redirect URL public function __construct(UrlGeneratorInterface $urlGenerator) { $this->urlGenerator = $urlGenerator; } // Tell Symfony which events we want to subscribe to public static function getSubscribedEvents(): array { return [ // Set priority to 20 (lower than RouterListener's 32) so we run AFTER route matching RequestEvent::class => ['onKernelRequest', 20], ]; } public function onKernelRequest(RequestEvent $event): void { // Skip subrequests (we only care about the main page request) if (!$event->isMainRequest()) { return; } $request = $event->getRequest(); $currentRoute = $request->attributes->get('_route'); $currentLocale = $request->getLocale(); // Replace 'english_test' with your actual route name for EnglishTestController // You can find your route name with `php bin/console debug:router` if ($currentRoute === 'english_test' && $currentLocale === 'es') { // Generate the absolute URL for the English version $englishTestUrl = $this->urlGenerator->generate( 'english_test', ['_locale' => 'en'], UrlGeneratorInterface::ABSOLUTE_URL ); // Use 301 for permanent redirect (good for SEO) or 302 for temporary $event->setResponse(new RedirectResponse($englishTestUrl, 301)); } } }
Step 2: Verify Key Details
Here are a few critical things to double-check:
- Route Name: Make sure
'english_test'matches the actual route name from your routing config. Runphp bin/console debug:routerto confirm this. - Auto-Registration: If your Symfony project has
autoconfigure: trueenabled (default in most setups), this subscriber will automatically be registered. If not, you'll need to add it to yourservices.yamlmanually. - Locale Configuration: Ensure your app is correctly detecting the user's locale (via URL prefix, cookies, etc.) so
$request->getLocale()returns 'es' for Spanish users.
Optional: Restrict Route to English Locale
To prevent the /es/englishTest route from even being accessible in the first place, you can add a requirement to your routing config:
# config/routes.yaml english_test: path: /{_locale}/englishTest controller: App\Controller\EnglishTestController::index requirements: _locale: en # Only allow 'en' as the locale for this route
Even with this, the subscriber is still useful for catching any edge cases (like old bookmarks or direct links) and redirecting them properly.
Troubleshooting Tips
If you're still having issues with the subscriber not firing:
- Clear your Symfony cache with
php bin/console cache:clear - Check that the subscriber is listed in
php bin/console debug:event-dispatcher kernel.request - Verify that the priority is set correctly (we use 20 to run after the router has matched the route)
内容的提问来源于stack exchange,提问作者dompie

