dlunire/dlroute

Sistema avanzado de enrutamiento HTTP impulsado por autómatas finitos. Altamente eficiente, flexible y de alto rendimiento. Úsalo como motor central de DLUnire o intégralo fácilmente en cualquier proyecto PHP.

Maintainers

Package info

github.com/dlunire/dlroute

pkg:composer/dlunire/dlroute

Fund package maintenance!

dlunire

Statistics

Installs: 270

Dependents: 1

Suggesters: 0

Stars: 1

Open Issues: 0

v1.0.11 2026-06-18 01:25 UTC

This package is auto-updated.

Last update: 2026-06-25 09:15:15 UTC


README

✨ Sponsors

Gracias a las siguientes personas y empresas por apoyar el desarrollo de DLRoute y la futura v2.0.0 (autómatas puros).

Patrocinadores Activos

¿Quieres formar parte de esto?

❤️ Patrocíname en GitHub Sponsors

DLRoute is not "another PHP router". It is a routing pipeline built on formal language theory — the same foundations used in compilers — applied to HTTP request dispatching for the first time in PHP.

composer require dlunire/dlroute

Requires PHP 8.2+. Works with any PHP project — with or without a framework.

Why DLRoute is different

Every other PHP router — FastRoute, Symfony Routing, Laravel Router — was built around one goal: map URLs to controllers as fast as possible. Matching was the problem. Everything else was secondary.

DLRoute was built around a different premise: routing is a formal processing pipeline, not a lookup table.

That premise produces an architecture that does not exist in any other PHP router.

What no other PHP router does

1. Finite automaton querystring parser

Every other router uses parse_str() — a PHP function that has existed since PHP 4.

DLRoute replaces it with a finite automaton that processes the querystring byte by byte in a single pass, with explicit states (QUERY_NAMEQUERY_VALUE), emitting immutable typed DTOs with the exact byte offset of each token in the original string.

// GET /?campo=valor&activo
$params = (new QueryParamComposer())->get_query_params();

$params['campo']->value;         // "valor"
$params['campo']->offset;        // 0   — byte position of the name
$params['campo']->offset_value;  // 6   — byte position of the value
$params['campo']->length;        // 5

$params['activo']->value;        // null — parameter without value

No other PHP router exposes byte-level position metadata for querystring parameters.

2. Route syntax lexer with exact-position diagnostics

When you define a route with invalid syntax, DLRoute does not throw a generic exception. The RouterLexer analyzes the route definition character by character and emits a fully actionable diagnostic:

// Invalid route
DLRoute::get('/{ciencia?=algo}/users', fn() => []);
RouteException: Expected closing brace (}) after «?» (position 9).
Received instead: «?=algo}/users».
Optional parameters must follow the format → «{param?}»
Route defined: «/{ciencia?=algo}/users»

Compare this to what Laravel does with an invalid HTTP method:

Laravel → silent 404 HTML page

DLRoute → structured JSON with exact error, file, line, and stack trace

That is the difference between a system with formal contracts and one without.

3. Telemetry as a first-class citizen of the core

TelemetryRequest lives in DLRoute\Core\Telemetry — not a middleware, not a plugin. It was designed from the start as part of the engine.

DLRoute::get('/{resource?}', function() {
    return TelemetryRequest::telemetry("My API");
});
{
    "message":     "My API",
    "route":       "/api/users",
    "uri":         "/api/users?filter=active",
    "base_url":    "https://my-domain.com",
    "domain":      "my-domain.com",
    "is_https":    true,
    "port":        443,
    "local_port":  80,
    "timestamp":   "2026-06-18T01:20:47+00:00",
    "cliente_ip":  "203.0.113.1",
    "method":      "GET",
    "proxy":       true,
    "query_param": {
        "filter": {
            "name":         "filter",
            "offset":       0,
            "value":        "active",
            "offset_value": 7,
            "length":       6
        }
    }
}

Single call. No configuration. Works correctly behind Cloudflare, Nginx reverse proxies, and tunnels — differentiating port (client-facing) from local_port (internal server port) automatically.

To achieve equivalent output in Laravel you need: Telescope + trusted proxy configuration + an external logging package.

4. Typed contracts in route registration

Methods::GET is an enum, not a string. The router validates the type before registering the route. If you pass something invalid, it fails immediately with a structured JSON error.

// ❌ Wrong
DLRoute::match(['david'], new RouteHandler(...));

// ✅ Correct
DLRoute::match([Methods::GET, Methods::POST], new RouteHandler(...));
{
    "status": false,
    "error": "DLRoute::match: Expected «DLRoute\\Enums\\Methods». Received «david» instead.",
    "details": { "filename": "...", "line": 200 }
}

Laravel silently responds with 404 HTML for the same input.

5. Zero-configuration subdirectory detection

DLRoute calculates the real request path via byte-position arithmetic — no str_replace(), no regular expressions:

OFFSET = LENGTH(dir) - 1
route  = substr(uri, OFFSET)

Deterministic and O(1), regardless of whether the subdirectory name appears repeated in the URI.

{
    "route":    "/api/products",
    "uri":      "/subdir/subdir/api/products",
    "dir":      "/subdir/subdir",
    "base_url": "https://example.com/subdir/subdir"
}

Feature comparison

Capability DLRoute FastRoute Symfony Router Laravel Router
Finite automaton querystring parser
Byte-level token position metadata
Route syntax lexer with diagnostics
Exact byte position on syntax errors
Native telemetry in the core
Structured JSON errors
Typed HTTP method contracts (enum)
Zero-config subdirectory detection
Automatic JSON response from array
Optional parameters natively workaround
Explicit MIME type per route
Zero external dependencies

Quick start

1. Project structure

my-project/
├── public/
│   └── index.php
├── app/
│   └── Controllers/
│       └── ApiController.php
└── vendor/

2. Entry point

<?php
declare(strict_types=1);

use DLRoute\Requests\DLRoute;

require dirname(__DIR__) . '/vendor/autoload.php';

// Define routes here

DLRoute::execute();

3. Basic route

DLRoute::get('/', fn() => ['status' => 'ok']);

Arrays and objects are automatically serialized as JSON with the correct Content-Type.

4. Route with typed parameter

DLRoute::get('/api/{id}', function(object $params) {
    return ['id' => $params->id];
})->filter_by_type(['id' => 'integer']);

If {id} is not an integer, DLRoute automatically responds with 404. No additional code needed.

5. Optional parameter

// Registers both /products and /products/{uuid}/detail simultaneously
DLRoute::get('/products/{uuid?}/detail', [ProductController::class, 'show'])
    ->filter_by_type(['uuid' => 'uuid']);

6. Multiple HTTP methods

use DLRoute\Core\Data\RouteHandler;
use DLRoute\Enums\Methods;

DLRoute::match(
    [Methods::GET, Methods::POST],
    new RouteHandler(
        uri:             '/api/{uuid}',
        controller:      [ApiController::class, 'handle'],
        mime_type:       'application/json',
        handler_filters: ['uuid' => 'uuid'],
    )
);

7. Supported parameter types

Type Description
string Any text string
uuid UUID format (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
email Valid email address
integer Integer number
float Decimal number
numeric Number with or without decimal
boolean Boolean value
password Min 8 chars, uppercase and special character

Custom regular expression:

->filter_by_type(['token' => '/^[a-f0-9]{64}$/'])

Supported HTTP methods

GET · HEAD · POST · PUT · PATCH · DELETE · OPTIONS

Part of the DLUnire ecosystem

DLRoute is the routing engine of DLUnire — a modern PHP framework for building API-oriented web applications rapidly and with formal rigor.

Support this project

DLRoute is MIT-licensed and free forever.

If your company depends on PHP infrastructure and values formal correctness over convention magic, consider sponsoring:

Corporate sponsorship tiers with logo placement, priority issue response, and architecture consulting are available. Contact: dlunireframework@gmail.com

Author

David E Luna M — Creator and lead developer of DLUnire

License

MIT