A lightweight HTTP routing library for PHP without external dependencies

v1.0.0-beta.6 2022-11-16 09:03 UTC

This package is auto-updated.

Last update: 2024-02-26 23:33:26 UTC


tests ci Latest Stable Version Latest Unstable Version Total Downloads License

A lightweight HTTP routing library for PHP. (WIP)


  • HTTP status codes
  • HTTP Methods
  • HTTP Headers
  • HTTP Requests
    • Handle multipart/form-data request data
    • Handle x-www-form-urlencoded request data
    • Handle application/xml request data
    • Handle application/json request data
    • Handle query URI request params
    • Access request path and headers
  • HTTP Responses
    • HTML, JSON, XML or Text responses
    • HTTP redirections
  • HTTP Routing
    • Routes with placeholder arguments: /abc/{some}
    • Handle multiple valid HTTP methods
    • Handle any valid HTTP method
    • Handle not match routes (404s)
    • Support callback or class/method style
    • Optional and order-insensitive arguments on callback or class/method handlers
    • Regular expressions support: /abc/regex(id=^[0-9]+$)
    • Optional route arguments: /abc/{some?}
    • Fallback routes
    • Route's cache
  • Middlewares
    • Inspect or filter valid requests before routing
    • Inspect or filter valid requests after routing

See Leap micro-framework based on Ruta.


PHP 8.0 or newer.


Install via Composer

composer require joseluisq/ruta:dev-master




require 'vendor/autoload.php';

use Ruta\Header;
use Ruta\Method;
use Ruta\Ruta;
use Ruta\Request;
use Ruta\Response;
use Ruta\Status;

// 1. Callback style

// NOTE: `Request`, `Response`, `array` (slug arguments) are passed to the callback.
// However they are optional and their order can be modified. See more examples below.

Ruta::get('/home/hola', function (Request $req, Response $res) {
        'host' => $req->header(Header::Host),
        'headers' => $req->headers(),
Ruta::get('/home/hola/redirect', function (Response $res) {
Ruta::get('/reg/regex(id=^[0-9]+$)/exp', function (Response $res, array $args) {
    $res->json(['args' => $args]);
Ruta::post('/home/{path3}/some2', function (Response $res) {
    $res->json(['post_data' => 11010101010]);

Ruta::some('/home/some', [Method::POST, Method::PUT], function (Request $req, Response $res) {
    $res->json(['only' => $req->method()]);

Ruta::any('/home/methods', function (Request $req, Response $res) {
    $res->json(['method' => $req->method()]);

Ruta::post('/home/{path}', function (Response $res) {
        ->header('X-Header-One', 'Header Value 1')
        ->header('X-Header-Two', 'Header Value 2')
        ->json(['some_data' => 223424234]);

// 2. class/method style
class HomeCtrl
    public function index(Request $req, Response $res, array $args)
        // 2.1 $args contains route placeholder values
        if (array_key_exists('path1', $args)) {
            // do something...

        // 2.2. Get data provided via `multipart/form-data` 
        $data = $req->multipart();
        // 2.3. Get all headers
        $data = $req->headers();
        // 2.4. Get a single header
        $data = $req->header("Host");
        // 2.5. Get data provided via `application/x-www-form-urlencoded` 
        $data = $req->urlencoded();
        // 2.6. Get data provided via `application/json`
        $data = $req->json();
        // 2.7. Get data provided via `application/xml`
        $data = $req->xml();
        // 2.8. Get query data
        $data = $req->query();

        $res->json(['data' => 'Message from a class!']);

    // Custom 404 reply
    public function not_found(Response $res)
            ->text("404 - Page Not Found!");

Ruta::get('/home/{path1}/some/{path2}', [HomeCtrl::class, 'index']);

// 3. Handle 404 not found routes
Ruta::not_found([HomeCtrl::class, 'not_found']);

Code example

File: example/nginx/public/index.php

# Or run example using Docker + Nginx server
make compose-up
# Run example using the PHP built-in server
make container-dev

Now navigate for example to http://localhost:8088/home/hola


Feel free to send a pull request or file some issue.


Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in current work by you, as defined in the Apache-2.0 license, shall be dual licensed as described below, without any additional terms or conditions.

Feel free to send some Pull request or issue.


This work is primarily distributed under the terms of both the MIT license and the Apache License (Version 2.0).

© 2021-present Jose Quintana