symfony/routing
Symfony Routing maps HTTP requests to configuration variables via flexible route definitions. Match incoming paths to controllers and parameters, and generate URLs from named routes using RouteCollection, UrlMatcher, UrlGenerator, and RequestContext.
Leverage Symfony's Routing component in Laravel via the built-in Illuminate/Routing facade, which internally uses Symfony's Routing component. No direct composer require is needed—it's a core dependency.
First Use Case: Define a Route
use Illuminate\Support\Facades\Route;
// Basic route definition (uses Symfony's Route class under the hood)
Route::get('/blog/{slug}', [BlogController::class, 'show'])
->name('blog.show');
Key Entry Points:
Route Facade: Laravel's wrapper for Symfony's RouteCollection.UrlGenerator: Access via route() helper or Illuminate\Routing\Router.UrlMatcher: Used internally by Laravel's middleware and controllers.Quick Test:
// Generate a URL
$url = route('blog.show', ['slug' => 'hello-world']);
// Match a request (simulate middleware logic)
$parameters = app('router')->getRoutes()->match(app('request')->create('/blog/hello-world'));
YAML/Array Syntax (Laravel's routes/web.php):
Route::get('/user/{id}', function ($id) {
// ...
})->name('user.profile');
// Equivalent Symfony Route object:
$route = new \Symfony\Component\Routing\Route(
'/user/{id}',
['_controller' => fn($id) => '...'],
['id' => '\d+'] // Requirements
);
Dynamic Routes with Attributes (Laravel 8+):
use Symfony\Component\Routing\Annotation\Route;
class BlogController {
#[Route('/posts/{slug}', name: 'posts.show')]
public function show(string $slug) { ... }
}
Basic Usage:
// Absolute URL
$url = route('blog.show', ['slug' => 'post'], false);
// Relative URL (e.g., for redirects)
$url = route('blog.show', ['slug' => 'post'], true);
Query Parameters:
$url = route('blog.show', [
'slug' => 'post',
'_query' => ['sort' => 'desc', 'page' => 1] // Symfony 6.0+ feature
]);
Middleware/Event Logic:
use Symfony\Component\HttpFoundation\Request;
public function handle(Request $request, Closure $next) {
$parameters = app('router')->getRoutes()->match($request);
// Custom logic using $parameters['_route'], $parameters['slug'], etc.
return $next($request);
}
Route::prefix('admin')->group(function () {
Route::get('/users', [UserController::class, 'index']);
// All routes here inherit `/admin` prefix.
});
Laravel auto-caches routes in bootstrap/cache/routes.php. Clear with:
php artisan route:clear
Case Sensitivity in Host Matching
host: '~^(?-i:example\.com)$~' in YAML or hostRegex: '/^(?-i:example\.com)$/' in PHP for case-insensitive matching.Numeric Query Parameters
_query parameters (e.g., ['page' => 1] works; [0 => 'page'] fails). Use associative arrays.Route Overrides
RouteServiceProvider merges routes from multiple files. Overrides are last-in-wins. Use Route::priority() to control precedence.Attribute Routes in Namespaces
#[Route] attributes are imported correctly:
use Symfony\Component\Routing\Annotation\Route;
Circular Dependencies in Route Loading
Route A referencing Route B which references Route A).Dump Route Parameters
dd(app('router')->getRoutes()->get('blog.show')->compile()->getVariables());
Check Matched Route
$request = app('request');
dd(app('router')->getRoutes()->match($request));
Validate Route Existence
if (!app('router')->getRoutes()->get('non.existent')) {
abort(404);
}
Clear Route Cache
php artisan route:clear
php artisan optimize:clear
Custom Route Compiler
Extend Symfony\Component\Routing\RouteCompiler to add logic (e.g., custom requirements):
use Symfony\Component\Routing\RouteCompilerInterface;
class CustomRouteCompiler implements RouteCompilerInterface {
public function compile(RouteCollection $routes) {
// Custom logic
return new CompiledRouteCollection($routes);
}
}
Route Loaders
Implement Symfony\Component\Routing\Loader\LoaderInterface for custom formats (e.g., JSON):
class JsonRouteLoader implements LoaderInterface {
public function load(string $resource, string $type = null) {
return new RouteCollection(json_decode(file_get_contents($resource), true));
}
}
Middleware Integration
Use Symfony\Component\HttpKernel\Event\RequestEvent to inspect routes:
public function onKernelRequest(RequestEvent $event) {
$request = $event->getRequest();
$parameters = app('router')->getRoutes()->match($request);
// ...
}
Route Model Binding
Laravel’s implicit model binding relies on Symfony’s Route requirements:
Route::get('/posts/{post}', [PostController::class, 'show'])
->where('post', '[0-9]+'); // Ensures binding to Post::find($post)
Avoid Dynamic Route Requirements Compile-time requirements (e.g., regex) are faster than runtime checks.
Cache Route Collections Laravel caches routes by default. Disable with:
'route.cache' => false,
in config/cache.php.
Use Route::getRoutes() Sparingly
Accessing app('router')->getRoutes() triggers compilation. Cache the result if reused:
$routes = app('router')->getRoutes();
// Reuse $routes instead of calling getRoutes() repeatedly.
How can I help you explore Laravel packages today?