Weave Code
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

Laminas Router Laravel Package

laminas/laminas-router

Laminas Router provides flexible, composable routing for PHP applications, with HTTP/console route types, route matching and assembly, and integration points for Laminas MVC/Mezzio. Includes CI-tested components and configurable route stacks.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup in Laravel
To integrate `laminas/laminas-router` into a Laravel project, start by installing it via Composer:

```bash
composer require laminas/laminas-router

First Use Case: Basic HTTP Route Matching Leverage the package to create a lightweight router alongside Laravel's built-in router for specialized needs (e.g., API versioning, legacy systems, or custom middleware chains). Example:

use Laminas\Router\Http\Segment;
use Laminas\Router\Http\TreeRouteStack;
use Laminas\Http\PhpEnvironment\Request;

// Create a request object (Laravel's Request can be adapted)
$request = new Request();

// Define a route (e.g., `/blog/{year}/{month}`)
$route = new Segment([
    'route'    => '/blog/:year/:month',
    'defaults' => ['controller' => 'BlogController', 'action' => 'index'],
    'specs'    => [
        'year'   => '[0-9]{4}',
        'month'  => '[0-9]{2}',
    ],
]);

// Build a router and match the request
$router = new TreeRouteStack();
$router->addRoute('blog', $route);

$match = $router->match($request);
if ($match) {
    // Route matched; extract params
    $params = $match->getParam('year'); // e.g., "2023"
}

Where to Look First

  • Laminas Router Docs for route types (Segment, Regex, Hostname, etc.).
  • Laravel Router Integration to understand how to hybridize with Laravel’s router.
  • TreeRouteStack for hierarchical route management (e.g., API versioning: /v1/users, /v2/users).

Implementation Patterns

1. Hybrid Routing with Laravel

Use Laminas Router for complex or legacy routes while letting Laravel handle the rest. Example:

// In a service provider (e.g., `AppServiceProvider`)
public function boot()
{
    $router = new TreeRouteStack();
    $router->addRoute('admin', new Segment([
        'route'    => '/admin/:action',
        'defaults' => ['controller' => 'AdminController'],
    ]));

    // Attach to Laravel's middleware pipeline
    $this->app->router->extend('admin', function ($request) use ($router) {
        $match = $router->match($request);
        if ($match) {
            return redirect()->route('admin', $match->getParams());
        }
    });
}

2. Dynamic Route Generation

Generate URLs dynamically using Laminas Router’s getUri() method:

$route = new Segment([
    'route'    => '/products/:id',
    'defaults' => ['controller' => 'ProductController', 'action' => 'show'],
]);
$router = new TreeRouteStack();
$router->addRoute('product', $route);

// Generate URL for product ID 42
$uri = $router->getUri()->setQuery(['id' => 42])->toString();
// Outputs: "/products/42"

3. Middleware Integration

Attach middleware to specific routes:

$route = new Segment([
    'route'    => '/secure',
    'defaults' => ['controller' => 'SecureController'],
    'may_terminate' => true, // Optional: for middleware termination
]);

// In Laravel's `HandleIncomingRequest` middleware
public function handle($request, Closure $next)
{
    $match = $router->match($request);
    if ($match && $match->getRouteName() === 'secure') {
        if (!auth()->check()) {
            return redirect()->route('login');
        }
    }
    return $next($request);
}

4. Console Routing

Laminas Router supports console commands too:

use Laminas\Router\Route\Console;

$consoleRoute = new Console([
    'route'    => 'cache:clear',
    'defaults' => ['command' => 'cache:clear'],
]);

$consoleRouter = new TreeRouteStack();
$consoleRouter->addRoute('cache-clear', $consoleRoute);

// Match a console command
$match = $consoleRouter->match(new Laminas\Console\ConsoleRequest('cache:clear'));

5. Route Prioritization

Use priority to control route matching order:

$route1 = new Segment(['route' => '/users', 'priority' => 10]);
$route2 = new Segment(['route' => '/users/:id', 'priority' => 20]);

$router = new TreeRouteStack();
$router->addRoute('users', $route1);
$router->addRoute('user', $route2); // Higher priority for dynamic routes

Gotchas and Tips

Pitfalls

  1. Case Sensitivity: Laminas Router is case-sensitive by default. For case-insensitive routes, use a Regex route:

    $route = new Regex([
        'route' => '/users/(?<id>[a-z0-9]+)',
        'defaults' => ['controller' => 'UserController'],
        'specs' => ['id' => 'i'], // 'i' flag for case-insensitive
    ]);
    
  2. Hostname Matching: Hostname routes require exact matches unless configured otherwise. Use Hostname route type:

    $route = new Hostname([
        'route' => 'api.example.com',
        'defaults' => ['controller' => 'ApiController'],
    ]);
    
  3. Query String Handling: Laminas Router ignores query strings by default. To include them, use Query route type or parse them manually:

    $request->getQuery()->toArray(); // Manually handle queries
    
  4. Route Matching Order: Routes are matched in the order they are added. Use priority or TreeRouteStack for hierarchical matching.

  5. Deprecated Properties: Avoid using priority as a dynamic property (deprecated). Instead, set it in the constructor:

    // Wrong (deprecated)
    $route->priority = 10;
    
    // Correct
    $route = new Segment(['route' => '/test', 'priority' => 10]);
    

Debugging Tips

  1. Dump Route Matches: Use var_dump($match->getParams()) to inspect matched parameters.

  2. Validate Routes: Test routes in isolation before integrating with Laravel:

    $request = new Request();
    $request->setUri('/blog/2023/05');
    $match = $router->match($request);
    assert($match !== null, "Route should match!");
    
  3. Laravel Request Adaptation: Convert Laravel’s Illuminate\Http\Request to Laminas PhpEnvironment\Request for compatibility:

    $laminasRequest = new Request();
    $laminasRequest->setUri($laravelRequest->getRequestUri())
                   ->setMethod($laravelRequest->getMethod());
    

Extension Points

  1. Custom Route Types: Extend Laminas\Router\Http\AbstractRoute to create domain-specific routes (e.g., ApiRoute for versioned APIs).

  2. Middleware Integration: Use Laminas Router’s mayTerminate flag to short-circuit Laravel’s middleware pipeline for specific routes.

  3. Route Caching: Cache compiled routes for performance:

    $router = new TreeRouteStack();
    $router->setCache(new \Laminas\Cache\Filesystem());
    
  4. Route Plugins: Use Laminas\Router\Http\RoutePluginManager to dynamically add route types or modifiers.

Performance Quirks

  • TreeRouteStack is optimized for hierarchical routes (e.g., /v1/users, /v2/users). Avoid flat structures with thousands of routes.
  • For high-traffic APIs, pre-compile routes and cache the router instance:
    $router = new TreeRouteStack();
    $router->setCache(new \Laminas\Cache\Psr6());
    

Laravel-Specific Workarounds

  1. Route Model Binding: Combine Laminas Router with Laravel’s implicit binding:

    $route = new Segment([
        'route' => '/posts/:id',
        'defaults' => ['controller' => 'PostController', 'action' => 'show'],
    ]);
    // Laravel will automatically bind the `id` to the `Post` model.
    
  2. Named Routes: Use Laminas Router’s name parameter to generate URLs via Laravel’s route() helper:

    $route = new Segment([
        'route' => '/posts/:id',
        'name' => 'posts.show',
    ]);
    // Generate URL: route('posts.show', ['id' => 1])
    
  3. API Resource Routing: For API resources, use Laminas Router to define versioned routes:

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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky