Skip to content
SoloPHPPublic

About

PHP router with an independent route builder, immutable runtime, typed results, and compiled matching.

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Repository files navigation

Solo Router 4

PHP router with a fluent route builder, immutable runtime routes, middleware metadata, groups, and advanced optional segment patterns.

Latest Version on Packagist PHP Version License

Upgrading from v3? Read the migration guide. Version 4 introduces a separate builder and immutable runtime.

Features

  • Separate builder and runtime — Configure a RouteCollector, then build() an immutable Router snapshot
  • Typed results — resolve() returns Matched, NotFound, or MethodNotAllowed
  • Compiled matching — Static routes use hash lookup; the dynamic routes of each method compile into one regex shaped as an order-preserving prefix tree
  • Fluent definitions — Chain name(), middleware(), and attribute() before building
  • URL generation — UrlGenerator builds the path of a named route, with encoded values checked against their patterns
  • Groups — Nested prefixes, middleware, and attributes
  • Advanced patterns — Optional segments anywhere, nested optionals, and regex constraints
  • Route cache — RouteCache keeps a built router in a PHP file that OPcache serves in under 2 µs per request, without registering or building routes
  • Build-time validation — Duplicate names/paths, routes that could never match, invalid syntax, and invalid regexes fail at build()
  • HEAD and 405 support — HEAD falls back to GET; method failures include allowed methods

Installation

composer require "solophp/router:^4.0"

Requires PHP 8.3 or later in the PHP 8 series and Composer. No runtime package dependencies. See installation for setup and integration changes.

Quick Example

require __DIR__ . '/vendor/autoload.php';

use Solo\Router\RouteCollector;
use Solo\Router\Results\Matched;
use Solo\Router\Results\MethodNotAllowed;
use Solo\Router\UrlGenerator;

$routes = new RouteCollector();
$routes->get('/users', [UserController::class, 'index']);
$routes->get('/users/{id}', [UserController::class, 'show'])
    ->name('users.show');

$routes->post('/posts', [PostController::class, 'store'])
    ->middleware(AuthMiddleware::class)
    ->name('posts.store')
    ->attribute('permission', 'posts.create');

$routes->group('/admin', function (RouteCollector $routes) {
    $routes->get('/dashboard', [AdminController::class, 'dashboard']);
}, [AuthMiddleware::class], ['permission' => 'admin']);

$router = $routes->build();
$result = $router->resolve('GET', '/users/123');

if ($result instanceof Matched) {
    $handler = $result->route->handler;
    $params = $result->params; // ['id' => '123']
    $middlewares = $result->route->middlewares;
    $name = $result->route->name;
    $attributes = $result->route->attributes;
    // Dispatch the handler and middleware in your application.
} elseif ($result instanceof MethodNotAllowed) {
    http_response_code(405);
    header('Allow: ' . implode(', ', $result->allowedMethods));
} else {
    http_response_code(404);
}

$urls = new UrlGenerator($router);
$urls->generate('users.show', ['id' => 123]); // '/users/123'

Changing a definition after build() affects subsequent builds only. Runtime routes have readonly properties. Handlers and object-valued attributes remain application-owned objects; the router does not deep-clone them.

Performance

Microseconds per lookup in a table of 1,000 GET routes, with PHP 8.4 and OPcache on one machine. A dash means the library does not support that layout or request with the measured API.

Layout and request Solo Router 4 Leaf 5 Symfony compiled Slim 4 (FastRoute)
/resourceN/{id}, match 0.43 0.54 0.57 2.07
/resourceN/{id}, 404 0.31 0.33 0.67 7.53
/resourceN/{id}, 405 0.44 — 4.39 2.28
/{lang:[a-z]{2}}/resourceN/{id}, match 0.53 — 0.73 7.61

Building 1,000 routes takes 1.2–2.8 ms; RouteCache loads a built router in under 2 µs. See the methodology and all layouts.

Documentation

The package requires only PHP. Route matching, URL generation, metadata, compilation, and route caching are its scope; applications handle dispatch.

Development

composer install
composer test

The test matrix covers PHP 8.3–8.5. See the release notes and performance measurements.

License

MIT License. See LICENSE.

About

PHP router with an independent route builder, immutable runtime, typed results, and compiled matching.

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages