zero-to-prod/http-router
最新稳定版本:v0.1.2
Composer 安装命令:
composer require zero-to-prod/http-router
包简介
High-performance HTTP router for PHP with three-level indexing, PSR-15 middleware support, and route caching
README 文档
README
High-performance HTTP router for PHP 7.2+ with three-level indexing, PSR-15 middleware support, and route caching.
Features
- High Performance: Three-level route indexing for O(1) static route lookup and optimized dynamic route matching
- PSR-15 Middleware: Full support for PSR-15 middleware alongside legacy variadic middleware
- Route Caching: Production-optimized serialization with automatic cache management
- RESTful Resources: Automatic generation of resourceful routes
- Route Groups: Organize routes with shared prefixes and middleware
- Named Routes: Generate URLs from route names with parameter substitution
- Parameter Constraints: Inline (
{id:\d+}) and fluent (where()) constraint syntax - PHP 7.1+ Compatible: Broad multi-version support
Installation
composer require zero-to-prod/http-router
Quick Start
use Zerotoprod\HttpRouter\HttpRouter; $router = HttpRouter::for($_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI']); $router->get('/users/{id}', [UserController::class, 'show']) ->where('id', '\d+') ->name('user.show') ->middleware(AuthMiddleware::class); $router->dispatch();
Basic Usage
Defining Routes
use Zerotoprod\HttpRouter\HttpRouter; // Create router and define routes $router = HttpRouter::create(); // Static routes $router->get('/', function() { echo 'Home'; }); // Dynamic routes with parameters $router->get('/users/{id}', function(array $params) { echo "User ID: " . $params['id']; }); // Routes with inline constraints $router->get('/posts/{id:\d+}', [PostController::class, 'show']); // Routes with fluent constraints $router->get('/users/{id}', [UserController::class, 'show']) ->where('id', '\d+'); // IMPORTANT: Set the request method and URI before dispatching $router->forRequest($_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI']); $router->dispatch();
Alternative Shorthand:
// Combine create() and forRequest() in one call $router = HttpRouter::for($_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI']); $router->get('/', function() { echo 'Home'; }); $router->dispatch();
HTTP Methods
$router->get('/users', [UserController::class, 'index']); $router->post('/users', [UserController::class, 'store']); $router->put('/users/{id}', [UserController::class, 'update']); $router->patch('/users/{id}', [UserController::class, 'patch']); $router->delete('/users/{id}', [UserController::class, 'destroy']); $router->options('/users', [UserController::class, 'options']); $router->head('/users', [UserController::class, 'head']); // Multiple methods $router->any('/users/{id}', [UserController::class, 'handler'], ['GET', 'POST']);
RESTful Resources
// Generates all 7 RESTful routes $router->resource('users', UserController::class); // With filters $router->resource('posts', PostController::class, ['only' => ['index', 'show']]); $router->resource('comments', CommentController::class, ['except' => ['destroy']]);
Generated routes:
GET /users→index()GET /users/create→create()POST /users→store()GET /users/{id}→show()GET /users/{id}/edit→edit()PUT /users/{id}→update()DELETE /users/{id}→destroy()
Route Groups
// Prefix groups $router->prefix('api/v1')->group(function($router) { $router->get('/users', [UserController::class, 'index']); // /api/v1/users }); // Middleware groups $router->middleware([AuthMiddleware::class])->group(function($router) { $router->get('/dashboard', [DashboardController::class, 'index']); }); // Combined $router->prefix('admin') ->middleware([AuthMiddleware::class, AdminMiddleware::class]) ->group(function($router) { $router->get('/users', [AdminController::class, 'users']); });
Named Routes
// Define named route $router->get('/users/{id}', [UserController::class, 'show']) ->name('user.show'); // Generate URL $url = $router->route('user.show', ['id' => 123]); // /users/123
Middleware
PSR-15 Middleware
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; class AuthMiddleware implements MiddlewareInterface { public function process( ServerRequestInterface $request, RequestHandlerInterface $handler ): ResponseInterface { // Check authentication return $handler->handle($request); } } $router->get('/dashboard', [DashboardController::class, 'index']) ->middleware(AuthMiddleware::class);
Variadic Middleware
class LogMiddleware { public function __invoke(callable $next, ...$context) { // Before request error_log('Request started'); $next(); // After request error_log('Request completed'); } } $router->get('/users', [UserController::class, 'index']) ->middleware(LogMiddleware::class);
Global Middleware
$router->globalMiddleware([ CorsMiddleware::class, SecurityHeadersMiddleware::class ]);
Route Caching
// Enable automatic caching in production $router->autoCache( cache_path: __DIR__ . '/cache/routes.php', env_var: 'APP_ENV', cache_envs: ['production'] ); // Manual caching if ($router->isCacheable()) { $compiled = $router->compile(); file_put_contents('routes.php', $compiled); } // Load from cache $data = file_get_contents('routes.php'); $router->loadCompiled($data);
Fallback Handler
$router->fallback(function() { http_response_code(404); echo 'Not Found'; });
Advanced Usage
Dispatching with Context
// Pass additional arguments to actions and middleware $router = Router::for('GET', '/users', $container, $request); $router->get('/users', function(array $params, $container, $request) { // Access container and request });
Optional Parameters
$router->get('/users/{id?}', function(array $params) { $id = $params['id'] ?? 'all'; echo "User: $id"; });
Multiple Constraints
$router->get('/posts/{year}/{month}/{slug}', [PostController::class, 'show']) ->where([ 'year' => '\d{4}', 'month' => '\d{2}', 'slug' => '[a-z0-9-]+' ]);
Action Types
The router supports three types of actions:
Controller Array
$router->get('/users', [UserController::class, 'index']);
Invokable Class
$router->get('/users', UserAction::class);
Closure
$router->get('/users', function(array $params) { echo 'Users'; });
Note: Closures cannot be cached due to PHP serialization limitations.
Performance
The router uses a three-level indexing strategy for optimal performance:
- Static Index (O(1)): Hash map
method:path→ Route for exact matches - Prefix Index (O(1) + O(n)): Hash map
method:prefix→ [Routes] for common prefixes - Method Index (O(n)): Hash map
method→ [Routes] as fallback
This approach minimizes regex matching for most common routing patterns.
Testing
composer test
License
MIT License. See LICENSE for details.
Contributing
Contributions are welcome! Please submit pull requests to the GitHub repository.
Support
- Issues: GitHub Issues
- Email: dave0016@gmail.com
- Documentation: https://zero-to-prod.github.io/http-router/
Credits
Created and maintained by David Smith.
统计信息
- 总下载量: 406
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 0
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-12-09