A fast, modern PHP router with production-grade middleware, signed & temporary URLs, smart responses, and first-class route caching.
- π Fast routing β Named routes, groups, domains, resources, attribute discovery
- π Signed URLs β Built-in URL signing with expiration and verification middleware
- βοΈ Production middleware β 15+ battle-tested middleware for security, caching, compression, CORS
- π¦ Smart responses β Auto content negotiation, streaming, downloads, JSON helpers
- πΎ Route caching β Sharded or fused cache for instant cold starts
- π Sudo PSR-compatible β Works with PSR-7/15/17 ecosystems
Requirements: PHP 8.4+ | Production-ready with OPcache + route caching
composer require infocyph/webrick<?php
use Infocyph\Webrick\Router\Kernel\RouterKernel;
use Infocyph\Webrick\Response\Response;
require __DIR__ . '/../vendor/autoload.php';
$router = new RouterKernel();
$router->get('/', fn() => Response::plaintext('Hello Webrick!'));
$router->get('/api/users/{id:int}', fn($r, int $id) =>
Response::json(['id' => $id, 'name' => 'John Doe'])
);
$router->run();<?php
use Infocyph\Webrick\Router\Kernel\RouterKernel;
use Infocyph\Webrick\Router\Definition\Registrar;
use Infocyph\Webrick\Response\Response;
$kernel = RouterKernel::bootWithRegistrar(
register: function (Registrar $r) {
$route = $r->facade();
$route::get('/users', [UserController::class, 'index'], 'users.index');
$route::post('/users', [UserController::class, 'store'], 'users.store');
$route::get('/protected', fn() => Response::json(['secret' => 'data']))
->middleware(['auth', 'verifySignedUrl']);
},
routeCache: __DIR__ . '/../var/cache/routes',
preGlobal: [
\Infocyph\Webrick\Middleware\GatewayHardeningMiddleware::class,
\Infocyph\Webrick\Middleware\ThrottleMiddleware::class,
\Infocyph\Webrick\Middleware\NegotiationMiddleware::class,
],
registrarOptions: [
'exposeUrlServices' => true,
'signKey' => $_ENV['WEBRICK_SIGN_KEY'] ?? 'change-me',
]
);
(new \Infocyph\Webrick\Response\Emitter\AutoEmitter())->emit(
$kernel->handle(\Infocyph\Webrick\Request\Request::capture())
);Run locally:
php -S 127.0.0.1:8080 -t public$route::get('/users/{id:int}', $handler, 'users.show');
$route::post('/users', $handler, 'users.store');
// Generate URLs
$url = Response::urlFor('users.show', ['id' => 42]); // /users/42
$absolute = Response::urlFor('users.show', ['id' => 42], absolute: true);// Generate signed URL
$signed = Response::signedUrlFor('download', ['file' => 'report.pdf']);
$temp = Response::temporaryUrlFor('download', ['file' => 'doc.pdf'], 3600); // 1 hour
// Protect route
$route::get('/download/{file}', $handler)
->middleware([\Infocyph\Webrick\Middleware\VerifySignedUrlMiddleware::class]);$route::group(prefix: '/api', middleware: ['auth', 'throttle:120,60'], callback: function() use ($route) {
$route::get('/users', [UserController::class, 'index']);
$route::post('/users', [UserController::class, 'store']);
});use Infocyph\Webrick\Router\Definition\Attribute\Get;
final class UserController {
#[Get('/users/{id:int}', name: 'users.show')]
public function show(int $id): Response {
return Response::json(['id' => $id]);
}
}
// Register in routes
AttributeRouteLoader::registerFromDirs($registrar, [
'App\\Http\\Routes\\' => __DIR__ . '/../src/Http/Routes',
]);// JSON
Response::json(['status' => 'ok']);
// Auto negotiation (based on Accept header)
Response::auto($request, ['data' => $items]);
// Downloads
Response::download('/path/to/file.pdf', 'report.pdf');
// Streaming
Response::stream(function() {
while ($data = getNextChunk()) {
echo json_encode($data) . "\n";
flush();
}
});
// Redirects
Response::redirect('/login');
Response::redirectToRoute('users.show', ['id' => 42]);| Middleware | Purpose |
|---|---|
| GatewayHardeningMiddleware | Security headers, host validation, IP filtering |
| ThrottleMiddleware | Rate limiting per IP/user |
| NegotiationMiddleware | Content negotiation (Accept, Accept-Language) |
| CorsAndPoliciesMiddleware | CORS + security policies (CSP, HSTS) |
| CompressionMiddleware | Response compression (gzip, brotli, zstd) |
| CookieEncryptionMiddleware | Transparent cookie encryption |
| ResponseCacheMiddleware | HTTP response caching |
| VerifySignedUrlMiddleware | Signed URL verification |
| TelemetryMiddleware | Request logging and W3C trace context |
π Full Documentation
- Routing β Routes, groups, parameters, constraints
- Requests β Reading input, headers, files
- Responses β JSON, redirects, downloads, streaming
- Middleware β Using and creating middleware
- Signed URLs β Secure, expiring URLs
- Route Caching β Production optimization
Route Caching dramatically improves cold-start performance:
# Build route cache (run in CI/deployment)
php bin/build-route-cache.php
# Result: ~100ms faster first requestProduction tips:
- β
Enable OPcache with
opcache.validate_timestamps=0 - β Prebuild route cache in CI/CD
- β Use persistent cache backend (Redis/APCu) for middleware
- β
Tune PHP-FPM pools (
pm.max_children,pm.start_servers)
# Run tests
composer test
# Code formatting
composer format
# Static analysis
composer analyseContributions welcome! Please:
- Fork and create a feature branch
- Write tests for new features
- Run
composer testandcomposer format - Submit a PR with clear description
- Documentation: https://docs.infocyph.com/projects/webrick/en/latest/
- Packagist: https://packagist.org/packages/infocyph/webrick
- Issues: https://github.com/infocyph/webrick/issues
- Changelog: CHANGELOG.md