Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Routing Laravel Package

symfony/routing

The Symfony Routing component maps an HTTP request to a set of configuration variables. It matches incoming URLs to routes and generates URLs from route names, supporting parameters, requirements, defaults, HTTP methods, and localized paths. Install it in any PHP project via Composer.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup in Laravel

symfony/routing is already pulled in transitively by laravel/framework, so check what you have before adding a constraint:

composer show symfony/routing
# only add an explicit constraint if you need a specific patched version
composer require symfony/routing:^5.4.54

Version note: the current LTS patch is v5.4.54, a security release that also fixes matching of the "0" URL (bug #65728). If you call Symfony's matcher directly (rather than only going through Laravel's router), bump to at least 5.4.54. The 8.1.0-BETA3 line is the forward branch — treat it as unstable for production and pin the 5.4 LTS if you need the guarantees.

First Use Case: Route Matching & URL Generation

Laravel already abstracts routing, but you can use Symfony's routing directly for custom logic:

use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\Generator\UrlGenerator;
use Symfony\Component\Routing\RequestContext;

// Define routes
$routes = new RouteCollection();
$routes->add('blog_show', new Route('/blog/{slug}', [
    '_controller' => 'App\Http\Controllers\BlogController@show',
]));

// Match a request
$context = new RequestContext();
$matcher  = new UrlMatcher($routes, $context);
$params   = $matcher->match('/blog/hello-world');

// Generate a URL
$generator = new UrlGenerator($routes, $context);
$url = $generator->generate('blog_show', ['slug' => 'hello-world']);

Where to Look First

  • Documentation: Symfony Routing Docs
  • Changelog: v5.4.53...v5.4.54
  • Laravel Integration: Use Illuminate\Routing\Router for Laravel-specific routing, but Symfony's routing is useful for:
    • Custom route matching logic
    • Generating URLs programmatically
    • Advanced route constraints
    • Route definitions that don't live in routes/*.php (DB/API-driven)

Implementation Patterns

1. Route Definitions

Define routes programmatically or via YAML/JSON (Symfony's format, but adaptable to Laravel):

// Programmatic route definition
$route = new Route('/user/{id}', [
    '_controller' => 'App\Http\Controllers\UserController@show',
], [
    'id' => '\d+', // requirements
]);
$route->setMethods(['GET', 'HEAD']);
$routes->add('user_show', $route);

Note the argument order: new Route($path, $defaults, $requirements, $options, $host, $schemes, $methods, $condition). Methods belong on the route, not in defaults.

2. Request Context Management

Use RequestContext to manage global routing parameters (base path, scheme, host, HTTP method):

$context = new RequestContext();
$context->setBaseUrl('/app');          // path prefix only, not a full URL
$context->setScheme('https');
$context->setHost('example.com');
$context->setMethod('GET');

In Laravel, derive it from the incoming request instead of hardcoding:

use Symfony\Component\Routing\RequestContext;

$context = (new RequestContext())->fromRequest($request);

3. URL Generation with Query Parameters

Anything not consumed by the path becomes the query string — pass it in the parameters array:

use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

$url = $generator->generate('blog_show', [
    'slug' => 'post-1',
    'page' => 2,
    'sort' => 'desc',
], UrlGeneratorInterface::ABSOLUTE_URL);
// https://example.com/blog/post-1?page=2&sort=desc

generate() takes exactly three arguments (name, parameters, referenceType); there is no separate "extra query" argument.

4. Route Matching with HTTP Method

Match routes while respecting HTTP methods:

$matcher = new UrlMatcher($routes, $context);
$params  = $matcher->matchRequest($request); // uses $request->getMethod() and host/scheme

Catch MethodNotAllowedException and use getAllowedMethods() to build a 405 with an Allow header.

5. Integration with Laravel Controllers

Bind the interfaces in a service provider and inject them:

use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

class BlogController extends Controller
{
    public function show(UrlGeneratorInterface $urlGenerator)
    {
        $url = $urlGenerator->generate('blog_show', ['slug' => 'test']);
        return view('blog.show')->with('url', $url);
    }
}
// AppServiceProvider::register()
$this->app->singleton(UrlGeneratorInterface::class, function ($app) {
    return new \Symfony\Component\Routing\Generator\UrlGenerator(
        $app['router']->getRoutes(), // Laravel's RouteCollection, not Symfony's
        $app['request_context']
    );
});

Only do this if you genuinely need Symfony's generator — Laravel's route()/URL::to() covers most cases and stays consistent with middleware and signed URLs.

6. Dynamic Route Loading

Load routes from external sources (e.g. API responses, database, tenant config):

$routes = new RouteCollection();
foreach ($apiRoutes as $name => $routeData) {
    $routes->add($name, new Route($routeData['path'], $routeData['defaults'] ?? []));
}

Build this once per boot and cache it — rebuilding on every request is the most common performance mistake here.

7. Route Constraints and Requirements

Define constraints for route parameters:

$route = new Route('/post/{year}/{month}/{day}', [], [
    'year'  => '\d{4}',
    'month' => '(0[1-9]|1[0-2])',
    'day'   => '(0[1-9]|[12][0-9]|3[01])',
]);

Gotchas and Tips

Pitfalls

  1. The "0" path/parameter bug (fixed in 5.4.54) Values that are the string "0" were falsy-checked in the matcher, so a route like /0 or a parameter literally equal to 0 could fail to match or be dropped. If you are pinned below 5.4.54, upgrade or avoid bare 0 segments.

  2. Security release 5.4.54 is flagged [SECURITY]. Treat this as a mandatory patch if any part of your stack calls Symfony's matcher/generator directly, and run composer audit after updating.

  3. Case Sensitivity in Host Matching Host-based routes are case-sensitive by default. Normalize with strtolower() (or RequestContext::setHost(strtolower($host))) if you need case-insensitive matching.

  4. Query Parameter Handling Route parameters and query parameters share one array. A key that matches a path placeholder is consumed; everything else is appended to the query string. Numeric keys (?0=value) get renumbered — prefer associative keys.

  5. URL Generation with Absolute Paths ABSOLUTE_URL requires a configured RequestContext (scheme, host, baseUrl); otherwise you get scheme-relative or path-only output. Use fromRequest() in Laravel rather than hand-setting values.

  6. Route Overrides Adding a route with an existing name silently replaces it. Check first:

    if ($routes->get($name) !== null) { /* prefix or skip */ }
    
  7. Circular References in Route Collections Avoid nesting a collection inside itself. Use RouteCollection::addCollection() for genuine nesting, and be careful with addPrefix() applied to an already-prefixed collection.

Debugging Tips

  1. Dump Route Parameters

    try {
        $params = $matcher->match('/path');
        dump($params);
    } catch (\Symfony\Component\Routing\Exception\ResourceNotFoundException $e) {
        dump('no match');
    }
    
  2. Check Route Requirements If a route isn't matching, the regex in requirements or a defaults value is the usual culprit — especially anchors (^...$ are added for you) and unescaped slashes.

  3. Enable Route Debugging in Laravel

    php artisan route:list
    

    Or dump the collection itself:

    dd(iterator_to_array($routes->getIterator()));
    

    Inspect $route->compile()->getRegex() to see exactly what the matcher is testing.

Configuration Quirks

  1. Request Context Persistence RequestContext is mutable and not request-isolated. Recreate it per request or bind it as a scoped singleton — sharing it across requests in a queue worker or Octane will leak host/scheme between requests.

  2. Host and Scheme Defaults Unconfigured context omits scheme and host from generated URLs. Set them explicitly, or derive from the request.

  3. Route Name Conflicts Laravel and Symfony route names live in different collections but can collide conceptually. Prefix Symfony-registered names (symfony_blog_show) to keep cache keys and debugging unambiguous.

  4. Compiled Route Cache Invalidation Cached/compiled routes key off the URL and requirements; changing a requirement without clearing the cache yields stale matches. Clear with php artisan route:clear and any custom cache key you introduced.

Extension Points

  1. Custom Route Loaders Implement Symfony\Component\Config\Loader\LoaderInterface to load routes from a database, tenant config, or remote API; tag it as a routing loader so the router picks it up.

  2. Route Compilation Use $route->compile() for pre-compiled regexes in performance-critical paths, and cache the resulting collection.

  3. Middleware Integration Wrap UrlMatcher in middleware to dispatch custom-registered routes before Laravel's router sees them; throw/abort 404 when ResourceNotFoundException is raised.

  4. Attribute-Based Routing Symfony's attribute/annotation loaders let you declare routes on controller methods; wire them through a custom loader if you want that style inside a Laravel app:

    use Symfony\Component\Routing\Loader\AttributeClassLoader;
    
    // subclass AttributeClassLoader and register it with a Config\Loader\LoaderResolver
    
  5. Route Caching Cache the built RouteCollection (serialize or dump to a compiled PHP array) and rebuild only when definitions change — never per request.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route