orbiit/router

A modern, lightweight PHP 8.5+ router focused on features and performance.

Maintainers

Package info

github.com/icordeiro/orbiit-router

pkg:composer/orbiit/router

Statistics

Installs: 6

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.1.0 2026-04-14 17:34 UTC

This package is auto-updated.

Last update: 2026-04-14 17:40:17 UTC


README

PHP Version License

Modern, fast and type-safe. The Orbiit Router is a PHP routing component built for high-performance SaaS and Retail applications. Leverages the power of native PHP 8.5 Attributes to provide a clean, declarative way to manage your application's flow.

Moderno, rápido e tipado. O Orbiit Router é um componente de rotas PHP construído para aplicações SaaS e Varejo de alta performance. Aproveita o poder dos Attributes nativos do PHP 8.5 para fornecer uma maneira limpa e declarativa de gerenciar o fluxo da sua aplicação.

Why Orbiit Router? (Por que Orbiit Router?)

The Orbiit Router was designed to overcome the limitations of centralized routing files. Instead of managing a massive routes.php file, Orbiit allows you to define your infrastructure directly where the logic happens.

  1. Decentralized Logic: Routes are defined in Controllers, making maintenance intuitive.
  2. Native PHP 8.5 Power: Uses Attributes and Enums for a 100% type-safe experience.
  3. Onion Pipeline: A robust middleware chain that allows pre and post-processing.

Highlights (Destaques)

  • Native Attributes: Define routes and groups directly in your controllers.
  • Onion Middleware Pipeline: Robust execution chain for request interception.
  • High Performance: Optimized Reflection and Regex dispatching.
  • Type Safe: Native support for PHP 8.5 Enums and strict typing.

Installation (Instalação)

Orbiit Router is available via Composer:

composer require orbiit/router

Server Configuration (Configuração do Servidor)

To use Orbiit Router, you must redirect all traffic to your index.php.

Apache (.htaccess)

RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)$ index.php?route=/$1 [L,QSA]

Nginx

location / {
    try_files $uri $uri/ /index.php?route=$uri&$args;
}

Quick Start (Início Rápido)

Define your Controller

namespace App\Controllers;

use Orbiit\Router\Attributes\{Route, Group};
use Orbiit\Router\Enums\Method;

#[Group(prefix: '/admin', middlewares: [AuthMiddleware::class])]
class DashboardController 
{
    #[Route(path: '/stats', method: Method::GET, name: 'admin.stats')]
    public function index(): string 
    {
        return "Welcome to the retail dashboard!";
    }

    #[Route(path: '/user/{id}', method: Method::DELETE)]
    public function delete(int $id): string // The 'id' is automatically cast to int!
    {
        return "User {$id} deleted!";
    }
}

RESTFul Example

#[Group(prefix: '/api/v1/products')]
class ProductController 
{
    #[Route(path: '/', method: Method::GET)]
    public function list(): array 
    {
        return ['product1', 'product2']; // List all
    }

    #[Route(path: '/', method: Method::POST)]
    public function store(): string 
    {
        return "Product created successfully!";
    }

    #[Route(path: '/{id}', method: Method::PUT)]
    public function update(int $id): string 
    {
        return "Product {$id} updated!";
    }

    #[Route(path: '/{id}', method: Method::DELETE)]
    public function destroy(int $id): string 
    {
        return "Product {$id} removed!";
    }
}

Note on HTTP Methods: Orbiit Router supports all HTTP verbs. When using native HTML forms (which only support GET/POST), you can easily implement "Method Spoofing" by passing the intended method through a hidden field or header and injecting it into the dispatch method.

Implement a Middleware

use Orbiit\Router\Contracts\MiddlewareInterface;

class AuthMiddleware implements MiddlewareInterface
{
    /**
     * Handle the incoming request.
     *
     * @param mixed    $request The request object or data.
     * @param callable $next The next middleware or the controller action.
     * @return mixed   The response generated.
     */
    public function handle(mixed $request, callable $next): mixed 
    {
        // Example: Simple Token Validation
        $token = $request['HTTP_AUTHORIZATION'] ?? null;
        
        if (!$token || $token !== 'your-secret-token') {
            http_response_code(401);
            return "Unauthorized Access";
        }

        return $next($request);
    }
}

Dispatch

require "vendor/autoload.php";

$router = new Orbiit\Router\Router("https://yourdomain.com");
$router->setNamespace('App\Controllers');
$router->loadController('DashboardController');

try {
    echo $router->dispatch($_SERVER['REQUEST_URI'], $_SERVER['REQUEST_METHOD']);
} catch (\Exception $e) {
    http_response_code(404);
    echo $e->getMessage();
}

🛠 Advanced Error Handling

Orbiit Router throws specialized exceptions, allowing you to catch specific errors and provide custom responses (like stylized 404 pages or JSON logs for your POS terminals).

use Orbiit\Router\Exceptions\{
    RouteNotFoundException, 
    MethodNotAllowedException, 
    MiddlewareException
};

try {
    echo $router->dispatch($_SERVER['REQUEST_URI'], $_SERVER['REQUEST_METHOD']);
} catch (RouteNotFoundException $e) {
    // Handle 404 Not Found
    http_response_code(404);
    echo "Custom 404: The requested resource does not exist.";
} catch (MethodNotAllowedException $e) {
    // Handle 405 Method Not Allowed (e.g., calling POST on a GET route)
    http_response_code(405);
    echo "Custom 405: Method not allowed for this route.";
} catch (MiddlewareException $e) {
    // Handle Security or Pipeline failures
    http_response_code(403);
    error_log("Security Alert: " . $e->getMessage());
    echo "Access Denied: Security policy violation.";
} catch (\Throwable $e) {
    // Catch-all for internal server errors
    http_response_code(500);
    echo "Internal Server Error: " . $e->getMessage();
}

💡 Pro Tips

1. Always implement the Interface

Ensure your middlewares implement Orbiit\Router\Contracts\MiddlewareInterface. If they don't, the Pipeline will throw a MiddlewareException.

2. Dependency Injection

The $next parameter in your middleware is a callable. To continue the request flow, you must return $next($request).

3. Namespace Auto-discovery

When using loadController, ensure the namespace matches your composer.json PSR-4 configuration.

Testing & Quality (Testes e Qualidade)

Pest PHP: 100% automated test coverage. • PHPStan: Level 8 static analysis for maximum safety.

Credits (Créditos)

License

The MIT License (MIT). Please see License File for more information.