Phprouter
PhpRouter is a full-featured yet very fast HTTP URL router for PHP projects
Install / Use
/learn @miladrahimi/PhprouterREADME
PhpRouter
PhpRouter is a full-featured yet very fast HTTP URL router for PHP projects.
Some of the provided features:
- Route parameters
- Predefined route parameter patterns
- Middleware
- Closure and class controllers/middleware
- Route groups (by prefix, middleware, and domain)
- Route naming (and generating route by name)
- PSR-7 requests and responses
- Views (simple PHP/HTML views)
- Multiple (sub)domains (using regex patterns)
- Custom HTTP methods
- Integrated with an IoC Container (PhpContainer)
- Method and constructor auto-injection of Request, Route, Url, etc
The current version requires PHP v8.0 or newer versions.
Contents
Versions
- v5.x.x (Current, Supported)
- v4.x.x
- v3.x.x
- v2.x.x
- v1.x.x
Documentation
Installation
Install Composer and run following command in your project's root directory:
composer require miladrahimi/phprouter "5.*"
Configuration
First of all,
you need to configure your webserver to handle all the HTTP requests with a single PHP file like the index.php file.
Here you can see sample configurations for NGINX and Apache HTTP Server.
-
NGINX configuration sample:
location / { try_files $uri $uri/ /index.php?$query_string; } -
Apache
.htaccesssample:<IfModule mod_rewrite.c> <IfModule mod_negotiation.c> Options -MultiViews </IfModule> RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)/$ /$1 [L,R=301] RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L] </IfModule>
Getting Started
It's so easy to work with PhpRouter! Just take a look at the following example.
-
JSON API Example:
use MiladRahimi\PhpRouter\Router; use Laminas\Diactoros\Response\JsonResponse; $router = Router::create(); $router->get('/', function () { return new JsonResponse(['message' => 'ok']); }); $router->dispatch(); -
View Example:
use MiladRahimi\PhpRouter\Router; use MiladRahimi\PhpRouter\View\View $router = Router::create(); $router->setupView('/../views'); $router->get('/', function (View $view) { return $view->make('profile', ['user' => 'Jack']); }); $router->dispatch();
HTTP Methods
The following example illustrates how to declare different routes for different HTTP methods.
use MiladRahimi\PhpRouter\Router;
$router = Router::create();
$router->get('/', function () { /* ... */ });
$router->post('/', function () { /* ... */ });
$router->put('/', function () { /* ... */ });
$router->patch('/', function () { /* ... */ });
$router->delete('/', function () { /* ... */ });
$router->dispatch();
You can use the define() method for other HTTP methods like this example:
use MiladRahimi\PhpRouter\Router;
$router = Router::create();
$router->define('GET', '/', function () { /* ... */ });
$router->define('OPTIONS', '/', function () { /* ... */ });
$router->define('CUSTOM', '/', function () { /* ... */ });
$router->dispatch();
If you don't care about HTTP verbs, you can use the any() method.
use MiladRahimi\PhpRouter\Router;
$router = Router::create();
$router->any('/', function () {
return 'This is Home! No matter what the HTTP method is!';
});
$router->dispatch();
Controllers
Closure Controllers
use MiladRahimi\PhpRouter\Router;
$router = Router::create();
$router->get('/', function () {
return 'This is a closure controller!';
});
$router->dispatch();
Class Method Controllers
use MiladRahimi\PhpRouter\Router;
class UsersController
{
function index()
{
return 'Class: UsersController & Method: index';
}
function handle()
{
return 'Class UsersController.';
}
}
$router = Router::create();
// Controller: Class=UsersController Method=index()
$router->get('/method', [UsersController::class, 'index']);
// Controller: Class=UsersController Method=handle()
$router->get('/class', UsersController::class);
$router->dispatch();
Route Parameters
A URL might have one or more variable parts like product IDs on a shopping website. We call it a route parameter. You can catch them by controller method arguments like the example below.
use MiladRahimi\PhpRouter\Router;
$router = Router::create();
// Required parameter
$router->get('/post/{id}', function ($id) {
return "The content of post $id";
});
// Optional parameter
$router->get('/welcome/{name?}', function ($name = null) {
return 'Welcome ' . ($name ?: 'Dear User');
});
// Optional parameter, Optional / (Slash)!
$router->get('/profile/?{user?}', function ($user = null) {
return ($user ?: 'Your') . ' profile';
});
// Optional parameter with default value
$router->get('/roles/{role?}', function ($role = 'guest') {
return "Your role is $role";
});
// Multiple parameters
$router->get('/post/{pid}/comment/{cid}', function ($pid, $cid) {
return "The comment $cid of the post $pid";
});
$router->dispatch();
Route Parameter Patterns
In default, route parameters can have any value, but you can define regex patterns to limit them.
use MiladRahimi\PhpRouter\Router;
$router = Router::create();
// "id" must be numeric
$router->pattern('id', '[0-9]+');
$router->get('/post/{id}', function (int $id) { /* ... */ });
$router->dispatch();
Requests and Responses
PhpRouter uses laminas-diactoros (formerly known as zend-diactoros) package (v2) to provide PSR-7 request and response objects to your controllers and middleware.
Requests
You can catch the request object in your controllers like this example:
use MiladRahimi\PhpRouter\Router;
use Laminas\Diactoros\ServerRequest;
use Laminas\Diactoros\Response\JsonResponse;
$router = Router::create();
$router->get('/', function (ServerRequest $request) {
$method = $request->getMethod();
$uriPath = $request->getUri()->getPath();
$headers = $request->getHeaders();
$queryParameters = $request->getQueryParams();
$bodyContents = $request->getBody()->getContents();
// ...
});
$router->dispatch();
Responses
The example below illustrates the built-in responses.
use Laminas\Diactoros\Response\RedirectResponse;
use MiladRahimi\PhpRouter\Router;
use Laminas\Diactoros\Response\EmptyResponse;
use Laminas\Diactoros\Response\HtmlResponse;
use Laminas\Diactoros\Response\JsonResponse;
use Laminas\Diactoros\Response\TextResponse;
$router = Router::create();
$router->get('/html/1', function () {
return '<html>This is an HTML response</html>';
});
$router->get('/html/2', function () {
return new HtmlResponse('<html>This is also an HTML response</html>', 200);
});
$router->get('/json', function () {
return new JsonResponse(['error' => 'Unauthorized!'], 401);
});
$router->get('/text', function () {
return new TextResponse('This is a plain text...');
});
$router->get('/empty', function () {
return new EmptyResponse(204);
});
$router->get('/redirect', function () {
return new RedirectResponse('https://miladrahimi.com');
});
$router->dispatch();
Views
You might need to create a classic-style server-side rendered (SSR) website that uses views. PhpRouter has a simple feature for working with PHP/HTML views. Look at the following example.
use MiladRahimi\PhpRouter\Router;
use MiladRahimi\PhpRouter\View\View
$router = Router::create();
// Setup view feature and set the directory of view files
$router->setupView(__DIR__ . '/../views');
$router->get('/profile', function (View $view) {
// It looks for a view with path: __DIR__/../views/profile.phtml
return $view->make('profile', ['user' => 'Jack']);
});
$router->get('/blog/post', function (View $view) {
// It looks for a view with path: __DIR__/../views/blog/post.phtml
return $view->make('blog.post', ['post' => $post]);
});
$router->dispatch();
There is also some points:
- View files must have the ".phtml" extension (e.g.
profile.phtml). - You can separate directories with
.(e.g.blog.postforblog/post.phtml).
View files are pure PHP or mixe
Related Skills
node-connect
339.1kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
83.8kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
339.1kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
83.8kCommit, push, and open a PR

