LilaPHP

Routing & REST API

Dual File-Based Routing & Dispatcher

LilaPHP eliminates complex routing regex tables and monolithic controller registration. Requests are directly mapped to physical endpoint scripts in app/routes/ for web views and app/routes/api/ for REST endpoints.

1. Dual Directory Architecture

The core dispatcher divides request handling into two distinct zones:

app/routes/
├── index.php             => GET /           (Web View)
├── about.php             => GET /about      (Web View)
├── contact.php           => GET/POST /contact
└── api/
    ├── index.php         => GET /api        (JSON API)
    ├── health.php        => GET /api/health (JSON API)
    └── users.php         => GET/POST/DELETE /api/users

Web View Routes (`/`)

Endpoints in app/routes/*.php handle browser page requests, rendering templates via View::render() with layouts, partials, and CSRF protection.

REST API Routes (`/api/*`)

Endpoints in app/routes/api/*.php handle stateless API requests, returning structured JSON via Response::json() with CORS and rate limiting.

2. HTTP Verbs & Handlers

Inside endpoint scripts, handle specific HTTP methods using static methods on Core\Request:

<?php
use Core\Request;
use Core\Response;
use Core\View;

Request::GET(function () {
    View::render('about', [
        'version' => '1.0.0'
    ], [
        'title' => 'About Us — LilaPHP'
    ]);
});

Request::POST(function () {
    $email = Request::input('email');
    return Response::json(['status' => 'received', 'email' => $email]);
});

3. Automatic 405 Method Not Allowed

In previous versions, endpoints required a manual Request::any() catch-all to reject unhandled HTTP methods. LilaPHP now tracks declared HTTP verbs automatically via Request::route().

If an endpoint only defines Request::GET() and an incoming request sends a POST:

  • The framework sets HTTP response status 405 Method Not Allowed.
  • An Allow: GET, HEAD header is emitted automatically.
  • For web requests, app/views/405.php is rendered.
  • For REST API requests, JSON is returned: {"error": "Method Not Allowed", "allowed": ["GET", "HEAD"]}.

4. Route Middlewares

Attach middlewares directly to verb handlers. Middlewares can be closures, class names, or arrays:

<?php
use Core\Request;
use Core\Response;

Request::POST([AuthMiddleware::class, RateLimitMiddleware::class], function () {
    $payload = Request::json();
    return Response::json(['status' => 'success', 'data' => $payload], 201);
});

5. SEO & Crawler Flags (`$noIndex`, `$protectedRoute`)

Declare route-level visibility flags to inform the automated sitemap and robots generator:

<?php
use Core\Request;
use Core\View;

$noIndex = true;
$protectedRoute = true;

Request::GET(function () {
    View::render('admin/dashboard');
});

When you run php cli.php sitemap or php cli.php robots, routes marked with $noIndex = true or $protectedRoute = true are automatically excluded from public/sitemap.xml and added to the Disallow list in public/robots.txt.

6. Custom Error Views (404 & 405)

LilaPHP provides customizable template files in app/views/ for HTTP errors:

  • app/views/404.php: Displayed when a web route does not exist.
  • app/views/405.php: Displayed when an unhandled HTTP method is requested.