Installation:
composer require symfony-cmf/routing
Ensure symfony/routing (v6+) is also installed as a dependency.
First Use Case:
DynamicRouter to match routes with dynamic parameters (e.g., {slug}) in a Laravel controller:
use SymfonyCmf\Routing\DynamicRouter;
use Symfony\Component\HttpFoundation\Request;
public function show(Request $request, DynamicRouter $router)
{
$match = $router->match($request->getPathInfo());
return view('page', ['content' => $match['_route_params']['slug']]);
}
Key Files:
config/routing.php (if created) for route definitions.app/Providers/RouteServiceProvider.php for binding the DynamicRouter to the container.Route Definition:
// config/routing.php
return [
'page_show' => [
'path' => '/page/{slug}',
'defaults' => ['_controller' => 'App\Controller\PageController::show'],
],
];
RouteServiceProvider:
public function boot()
{
$loader = new \Symfony\Component\Routing\Loader\YamlFileLoader(
new \Symfony\Component\Config\FileLocator(__DIR__.'/../config')
);
$router = new DynamicRouter($loader->load('routing.yaml'));
$this->app->singleton(DynamicRouter::class, fn() => $router);
}
Route Matching:
DynamicRouter in controllers/middleware:
$match = $router->match('/blog/laravel-tips');
// Returns: ['_route' => 'page_show', '_route_params' => ['slug' => 'laravel-tips']]
Generating URLs:
$url = $router->generate('page_show', ['slug' => 'laravel-tips']);
// Returns: '/page/laravel-tips'
Laravel Middleware:
Bind DynamicRouter to middleware for route-aware logic:
public function handle($request, Closure $next)
{
$match = $this->router->match($request->getPathInfo());
if ($match['_route'] === 'admin_dashboard') {
// Custom logic
}
return $next($request);
}
Route Caching: Cache route collections for performance:
$router = new DynamicRouter($loader->load('routing.yaml'));
$router->getRouteCollection()->compile();
Hybrid Routing: Combine with Laravel’s native router for flexibility:
Route::get('/legacy', function () {
return 'Legacy route';
});
Route Overrides:
DynamicRouter is used before Laravel’s router in middleware/service providers to avoid conflicts.Parameter Validation:
$slug = $match['_route_params']['slug'];
if (!preg_match('/^[a-z0-9\-]+$/', $slug)) {
abort(404);
}
Case Sensitivity:
$request->setPathInfo(strtolower($request->getPathInfo()));
Circular Dependencies:
dd($router->getRouteCollection()->getResources());
SYMFONY_ROUTER_DEBUG=1 in .env to log route matching details.Custom Route Loaders:
Extend YamlFileLoader or XmlFileLoader for custom formats (e.g., JSON):
use Symfony\Component\Routing\Loader\JsonFileLoader;
Route Builders:
Use RouteBuilder for programmatic route generation:
$routeBuilder = new RouteBuilder();
$routeBuilder->add('home', '/');
$router = new DynamicRouter($routeBuilder->getRouteCollection());
Route Events:
Subscribe to ROUTE_MATCH and ROUTE_GENERATE events (via Symfony EventDispatcher) for pre/post-processing.
Laravel Service Provider:
Override Laravel’s RouteServiceProvider to integrate DynamicRouter seamlessly:
protected function mapApiRoutes()
{
$router = app(DynamicRouter::class);
// Use $router->match()/$router->generate() here
}
$routeCollection->add('fallback', new Route('/{path}', [], [], [], 'GET', [], [], false));
How can I help you explore Laravel packages today?