derafu/routing

Derafu: Routing - Elegant PHP Router with Plugin Architecture.

dev-main 2025-02-21 12:47 UTC

This package is auto-updated.

Last update: 2025-02-21 12:48:23 UTC


README

CI Workflow License

A lightweight, extensible PHP routing library that combines simplicity with power through its unique 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.

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');
$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');

DynamicParser

Supports parameters and patterns:

$router->addRoute('/users/{id:\d+}', 'UserController@show');
$router->addRoute('/blog/{year}/{slug}', 'BlogController@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

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.

License

This library is licensed under the MIT License. See the LICENSE file for more details.