Download the PHP package sodaho/php-router without Composer
On this page you can find all versions of the php package sodaho/php-router. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Informations about the package php-router
php-router
Lightweight PHP Router for REST APIs and SPAs. Standardized JSON responses, middleware, caching.
Why This Library?
What it does:
- PSR-7/PSR-15 compliant routing with typed route parameters and auto-casting
- Standardized JSON response format (pluggable via
ResponderInterface) - Route caching with HMAC integrity verification
- Middleware, route groups, named routes, URL generation
What it deliberately does not:
- No optional route segments, no inline regex, no route priority system
- No CORS, CSRF, authentication, or rate limiting (use middleware)
- No async/Swoole runtime (use
handle()+ your own emitter) - Not optimized for >500 dynamic routes (O(n) matching)
Installation
Quick Start
routes.php:
Controller:
HTTP Methods
Route Parameters
Available Patterns
| Shorthand | Regex | Example |
|---|---|---|
int |
-?\d+ |
{id:int} → 123, -5 |
float |
-?\d+(?:\.\d+)? |
{price:float} → 19.99 |
bool |
true\|false\|0\|1 (case-insensitive) |
{active:bool} → true, TRUE |
alpha |
[a-zA-Z]+ |
{name:alpha} → abc |
alphanum |
[a-zA-Z0-9]+ |
{code:alphanum} → abc123 |
slug |
[a-z0-9-]+ |
{slug:slug} → my-post |
uuid |
[0-9a-fA-F]{8}-... |
{id:uuid} → 550e8400-... |
ulid |
[0-9A-Za-z]{26} |
{id:ulid} → 01ARZ3NDEKTSV4RRFFQ69G5FAV |
any |
.* |
{path:any} → anything/here |
Custom Patterns
Accessing Parameters
Route Groups
Middleware
Route parameters are available in middleware:
Named Routes & URL Generation
Redirect Routes
Response Helpers
Success Responses
Error Responses
Other Responses
JSON Structure
Success:
Error:
Configuration
Via Config Array
Via Environment Variables
Via Fluent API
Options
| Config Key | ENV Variable | Default | Description |
|---|---|---|---|
debug |
APP_DEBUG |
false |
Enable debug mode (detailed errors) |
| - | APP_ENV |
production |
If dev/local/development → debug=true |
basePath |
ROUTER_BASE_PATH |
'' |
URL prefix for all routes |
baseUrl |
APP_URL |
null |
Base URL for absoluteUrl() |
trailingSlash |
ROUTER_TRAILING_SLASH |
'strict' |
'strict' or 'ignore' |
cacheFile |
ROUTER_CACHE_FILE |
null |
Path to cache file |
cacheSignature |
ROUTER_CACHE_KEY |
null |
HMAC key for cache integrity |
Caching
Note: Closures cannot be cached. Use [Controller::class, 'method'] syntax.
Hooks (Logging)
Note: Hook exceptions are caught and logged to stderr. They never affect the response.
PSR-15 Compatibility
Dependency Injection
Exceptions
All exceptions extend RouterException:
| Exception | When |
|---|---|
NotFoundException |
Available for application use (router returns 404 response directly) |
MethodNotAllowedException |
Available for application use (router returns 405 response directly) |
RouteNotFoundException |
Named route doesn't exist (URL generation) |
DuplicateRouteException |
Same method+pattern registered twice |
CacheException |
Cache read/write/signature failure |
Trailing Slash Handling
SPA Catch-All (Vue/React)
Quick Boot
Webserver Configuration
Apache (.htaccess)
nginx
Custom Response Formats
The router uses JsonResponder by default. You can swap it for RFC 7807 or custom formats:
Create your own responder:
Reset in tests:
Limitations
What this router does NOT support:
| Feature | Reason |
|---|---|
Optional segments [/suffix] |
Complexity vs. benefit. Define two routes instead. |
| Regex in route patterns | Use predefined patterns or addPattern(). |
| Route priority/ordering | Routes match in definition order. Define specific routes first. |
| Async/Swoole out-of-box | Use handle() method, not run(). Emit response yourself. |
| >500 dynamic routes efficiently | O(n) matching. Consider splitting into microservices. |
Workarounds:
Performance
Route Caching
Always enable caching in production:
| Mode | 50 Routes | 200 Routes |
|---|---|---|
| No cache | ~2-5ms | ~5-15ms |
| With cache | ~0.1ms | ~0.2ms |
Route Matching Complexity
| Route Type | Complexity | Example |
|---|---|---|
| Static | O(1) | /users, /api/health |
| Dynamic | O(n) | /users/{id}, /posts/{slug} |
Tips:
- Static routes are instant (hash lookup)
- Dynamic routes loop through candidates
- Define most-used routes first
- Keep dynamic routes under 500 for best performance
Memory
- Route cache uses OPcache (no memory parsing)
- ~1KB per route in memory
- 100 routes ≈ 100KB memory footprint
Security Best Practices
Open Redirect Prevention
Never redirect to user input without validation:
CSRF Protection
This router does not include CSRF protection. For state-changing operations:
Input Validation
Route parameter types ({id:int}) validate format, not business logic:
Debug Mode
Never enable debug mode in production:
Testing
Requirements
- PHP ^8.2
- PSR-7 HTTP Message (nyholm/psr7)
- PSR-15 HTTP Handler/Middleware
Acknowledgments
Parts of this project (refactoring, documentation, code review) were developed with AI assistance (Claude).
License
MIT
All versions of php-router with dependencies
psr/http-message Version ^2.0
psr/http-server-handler Version ^1.0
psr/http-server-middleware Version ^1.0
psr/container Version ^2.0
psr/http-factory Version ^1.0
nyholm/psr7 Version ^1.8
nyholm/psr7-server Version ^1.1