derafu / routing
Derafu: Routing - Elegant PHP Router with Plugin Architecture.
Requires
- php: ^8.3
- derafu/translation: dev-main
Requires (Dev)
- ext-xdebug: *
- derafu/foundation: dev-main
- friendsofphp/php-cs-fixer: ^3.63
- phpstan/phpstan: ^1.12
- phpunit/phpunit: ^11.4
This package is auto-updated.
Last update: 2025-05-08 20:21:40 UTC
README
A lightweight, extensible PHP routing library that combines simplicity with power through its parser-based architecture.
Features
- ๐ Plugin architecture with swappable parsers.
- ๐ฏ Multiple routing strategies (static, dynamic, filesystem).
- ๐งฉ Easy to extend with custom parsers.
- ๐ Built-in filesystem routing for static sites.
- ๐ Support for different content types (.md, .twig, etc.).
- ๐ ๏ธ Clean separation of concerns.
- ๐ชถ Lightweight with zero dependencies.
- โก Fast pattern matching.
- ๐งช Comprehensive test coverage.
- ๐ URL generation for named routes.
Why Derafu\Routing?
Unlike traditional monolithic routers, Derafu\Routing uses a unique parser-based architecture that offers several advantages:
- Modularity: Each routing strategy is encapsulated in its own parser.
- Flexibility: Easy to add new routing patterns without modifying existing code.
- Clarity: Clear separation between route matching and request handling.
- Extensibility: Add custom parsers for specific routing needs.
- Predictability: Each parser has a single responsibility.
- Performance: Only load the parsers you need.
Installation
Install via Composer:
composer require derafu/routing
Basic Usage
use Derafu\Routing\Router; use Derafu\Routing\Dispatcher; use Derafu\Routing\Parser\StaticParser; use Derafu\Routing\Parser\FileSystemParser; // Create and configure router. $router = new Router(); $router->addParser(new StaticParser()); $router->addParser(new FileSystemParser([__DIR__ . '/pages'])); // Add routes. $router->addRoute('/', 'HomeController::index', name: 'home'); $router->addDirectory(__DIR__ . '/pages'); // Create and configure dispatcher. $dispatcher = new Dispatcher([ 'md' => fn ($file, $params) => renderMarkdown($file), 'twig' => fn($file, $params) => renderTwig($file, $params), ]); // Handle request. try { $route = $router->match(); echo $dispatcher->dispatch($route); } catch (RouterException $e) { // Handle error. }
Available Parsers
StaticParser
Handles exact route matches:
$router->addRoute('/about', 'PagesController::about', name: 'about');
DynamicParser
Supports parameters and patterns:
$router->addRoute('/users/{id:\d+}', 'UserController::show', name: 'user.show'); $router->addRoute('/blog/{year}/{slug}', 'BlogController::post', name: 'blog.post');
FileSystemParser
Maps URLs to files in directories:
$router->addDirectory(__DIR__ . '/pages'); // Examples: // /about maps to /pages/about.md // /contact maps to /pages/contact.html.twig
URL Generation
Generate URLs for named routes:
// Set request context (needed for absolute URLs). $router->setContext(new RequestContext( baseUrl: '/myapp', scheme: 'https', host: 'example.com' )); // Generate URLs. $url = $router->generate('user.show', ['id' => 123]); // /myapp/users/123 $url = $router->generate('blog.post', [ 'year' => '2024', 'slug' => 'hello-world' ]); // /myapp/blog/2024/hello-world // Generate absolute URL. $url = $router->generate('about', [], UrlReferenceType::ABSOLUTE_URL); // https://example.com/myapp/about
Creating Custom Parsers
Implement your own routing strategy by creating a parser:
class CustomParser implements ParserInterface { public function parse(string $uri, array $routes): ?RouteMatch { // Your custom routing logic. } public function supports(Route $route): bool { // Define what routes this parser can handle. } } $router->addParser(new CustomParser());
File-based Routing Example
Perfect for static sites:
pages/
โโโ about.md
โโโ contact.html.twig
โโโ blog/
โโโ post-1.md
โโโ post-2.md
URLs are automatically mapped to files:
/about
โpages/about.md
/contact
โpages/contact.html.twig
/blog/post-1
โpages/blog/post-1.md
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
License
This package is open-sourced software licensed under the MIT license.