A lightweight and simple object oriented PHP Router

Related tags

Routers php routing
Overview

bramus/router

Build Status Source Version Downloads License

A lightweight and simple object oriented PHP Router. Built by Bram(us) Van Damme (https://www.bram.us) and Contributors

Features

Prerequisites/Requirements

Installation

Installation is possible using Composer

composer require bramus/router ~1.5

Demo

A demo is included in the demo subfolder. Serve it using your favorite web server, or using PHP 5.4+'s built-in server by executing php -S localhost:8080 on the shell. A .htaccess for use with Apache is included.

Additionally a demo of a mutilingual router is also included. This can be found in the demo-multilang subfolder and can be ran in the same manner as the normal demo.

Usage

Create an instance of \Bramus\Router\Router, define some routes onto it, and run it.

// Require composer autoloader
require __DIR__ . '/vendor/autoload.php';

// Create Router instance
$router = new \Bramus\Router\Router();

// Define routes
// ...

// Run it!
$router->run();

Routing

Hook routes (a combination of one or more HTTP methods and a pattern) using $router->match(method(s), pattern, function):

$router->match('GET|POST', 'pattern', function() { … });

bramus/router supports GET, POST, PUT, PATCH, DELETE, HEAD (see note), and OPTIONS HTTP request methods. Pass in a single request method, or multiple request methods separated by |.

When a route matches against the current URL (e.g. $_SERVER['REQUEST_URI']), the attached route handling function will be executed. The route handling function must be a callable. Only the first route matched will be handled. When no matching route is found, a 404 handler will be executed.

Routing Shorthands

Shorthands for single request methods are provided:

$router->get('pattern', function() { /* ... */ });
$router->post('pattern', function() { /* ... */ });
$router->put('pattern', function() { /* ... */ });
$router->delete('pattern', function() { /* ... */ });
$router->options('pattern', function() { /* ... */ });
$router->patch('pattern', function() { /* ... */ });

You can use this shorthand for a route that can be accessed using any method:

$router->all('pattern', function() { … });

Note: Routes must be hooked before $router->run(); is being called.

Note: There is no shorthand for match() as bramus/router will internally re-route such requrests to their equivalent GET request, in order to comply with RFC2616 (see note).

Route Patterns

Route Patterns can be static or dynamic:

  • Static Route Patterns contain no dynamic parts and must match exactly against the path part of the current URL.
  • Dynamic Route Patterns contain dynamic parts that can vary per request. The varying parts are named subpatterns and are defined using either Perl-compatible regular expressions (PCRE) or by using placeholders

Static Route Patterns

A static route pattern is a regular string representing a URI. It will be compared directly against the path part of the current URL.

Examples:

  • /about
  • /contact

Usage Examples:

// This route handling function will only be executed when visiting http(s)://www.example.org/about
$router->get('/about', function() {
    echo 'About Page Contents';
});

Dynamic PCRE-based Route Patterns

This type of Route Patterns contain dynamic parts which can vary per request. The varying parts are named subpatterns and are defined using regular expressions.

Examples:

  • /movies/(\d+)
  • /profile/(\w+)

Commonly used PCRE-based subpatterns within Dynamic Route Patterns are:

  • \d+ = One or more digits (0-9)
  • \w+ = One or more word characters (a-z 0-9 _)
  • [a-z0-9_-]+ = One or more word characters (a-z 0-9 _) and the dash (-)
  • .* = Any character (including /), zero or more
  • [^/]+ = Any character but /, one or more

Note: The PHP PCRE Cheat Sheet might come in handy.

The subpatterns defined in Dynamic PCRE-based Route Patterns are converted to parameters which are passed into the route handling function. Prerequisite is that these subpatterns need to be defined as parenthesized subpatterns, which means that they should be wrapped between parens:

// Bad
$router->get('/hello/\w+', function($name) {
    echo 'Hello ' . htmlentities($name);
});

// Good
$router->get('/hello/(\w+)', function($name) {
    echo 'Hello ' . htmlentities($name);
});

Note: The leading / at the very beginning of a route pattern is not mandatory, but is recommended.

When multiple subpatterns are defined, the resulting route handling parameters are passed into the route handling function in the order they are defined in:

$router->get('/movies/(\d+)/photos/(\d+)', function($movieId, $photoId) {
    echo 'Movie #' . $movieId . ', photo #' . $photoId;
});

Dynamic Placeholder-based Route Patterns

This type of Route Patterns are the same as Dynamic PCRE-based Route Patterns, but with one difference: they don't use regexes to do the pattern matching but they use the more easy placeholders instead. Placeholders are strings surrounded by curly braces, e.g. {name}. You don't need to add parens around placeholders.

Examples:

  • /movies/{id}
  • /profile/{username}

Placeholders are easier to use than PRCEs, but offer you less control as they internally get translated to a PRCE that matches any character (.*).

$router->get('/movies/{movieId}/photos/{photoId}', function($movieId, $photoId) {
    echo 'Movie #' . $movieId . ', photo #' . $photoId;
});

Note: the name of the placeholder does not need to match with the name of the parameter that is passed into the route handling function:

$router->get('/movies/{foo}/photos/{bar}', function($movieId, $photoId) {
    echo 'Movie #' . $movieId . ', photo #' . $photoId;
});

Optional Route Subpatterns

Route subpatterns can be made optional by making the subpatterns optional by adding a ? after them. Think of blog URLs in the form of /blog(/year)(/month)(/day)(/slug):

$router->get(
    '/blog(/\d+)?(/\d+)?(/\d+)?(/[a-z0-9_-]+)?',
    function($year = null, $month = null, $day = null, $slug = null) {
        if (!$year) { echo 'Blog overview'; return; }
        if (!$month) { echo 'Blog year overview'; return; }
        if (!$day) { echo 'Blog month overview'; return; }
        if (!$slug) { echo 'Blog day overview'; return; }
        echo 'Blogpost ' . htmlentities($slug) . ' detail';
    }
);

The code snippet above responds to the URLs /blog, /blog/year, /blog/year/month, /blog/year/month/day, and /blog/year/month/day/slug.

Note: With optional parameters it is important that the leading / of the subpatterns is put inside the subpattern itself. Don't forget to set default values for the optional parameters.

The code snipped above unfortunately also responds to URLs like /blog/foo and states that the overview needs to be shown - which is incorrect. Optional subpatterns can be made successive by extending the parenthesized subpatterns so that they contain the other optional subpatterns: The pattern should resemble /blog(/year(/month(/day(/slug)))) instead of the previous /blog(/year)(/month)(/day)(/slug):

$router->get('/blog(/\d+(/\d+(/\d+(/[a-z0-9_-]+)?)?)?)?', function($year = null, $month = null, $day = null, $slug = null) {
    // ...
});

Note: It is highly recommended to always define successive optional parameters.

To make things complete use quantifiers to require the correct amount of numbers in the URL:

$router->get('/blog(/\d{4}(/\d{2}(/\d{2}(/[a-z0-9_-]+)?)?)?)?', function($year = null, $month = null, $day = null, $slug = null) {
    // ...
});

Subrouting / Mounting Routes

Use $router->mount($baseroute, $fn) to mount a collection of routes onto a subroute pattern. The subroute pattern is prefixed onto all following routes defined in the scope. e.g. Mounting a callback $fn onto /movies will prefix /movies onto all following routes.

$router->mount('/movies', function() use ($router) {

    // will result in '/movies/'
    $router->get('/', function() {
        echo 'movies overview';
    });

    // will result in '/movies/id'
    $router->get('/(\d+)', function($id) {
        echo 'movie id ' . htmlentities($id);
    });

});

Nesting of subroutes is possible, just define a second $router->mount() in the callable that's already contained within a preceding $router->mount().

Class@Method calls

We can route to the class action like so:

$router->get('/(\d+)', '\App\Controllers\User@showProfile');

When a request matches the specified route URI, the showProfile method on the User class will be executed. The defined route parameters will be passed to the class method.

The method can be static (recommended) or non-static (not-recommended). In case of a non-static method, a new instance of the class will be created.

If most/all of your handling classes are in one and the same namespace, you can set the default namespace to use on your router instance via setNamespace()

$router->setNamespace('\App\Controllers');
$router->get('/users/(\d+)', 'User@showProfile');
$router->get('/cars/(\d+)', 'Car@showProfile');

Custom 404

The default 404 handler sets a 404 status code and exits. You can override this default 404 handler by using $router->set404(callable);

$router->set404(function() {
    header('HTTP/1.1 404 Not Found');
    // ... do something special here
});

You can also define multiple custom routes e.x. you want to define an /api route, you can print a custom 404 page:

$router->set404('/api(/.*)?', function() {
    header('HTTP/1.1 404 Not Found');
    header('Content-Type: application/json');

    $jsonArray = array();
    $jsonArray['status'] = "404";
    $jsonArray['status_text'] = "route not defined";

    echo json_encode($jsonArray);
});

Also supported are Class@Method callables:

$router->set404('\App\Controllers\Error@notFound');

The 404 handler will be executed when no route pattern was matched to the current URL.

💡 You can also manually trigger the 404 handler by calling $router->trigger404()

$router->get('/([a-z0-9-]+)', function($id) use ($router) {
    if (!Posts::exists($id)) {
        $router->trigger404();
        return;
    }

    // …
});

Before Route Middlewares

bramus/router supports Before Route Middlewares, which are executed before the route handling is processed.

Like route handling functions, you hook a handling function to a combination of one or more HTTP request methods and a specific route pattern.

$router->before('GET|POST', '/admin/.*', function() {
    if (!isset($_SESSION['user'])) {
        header('location: /auth/login');
        exit();
    }
});

Unlike route handling functions, more than one before route middleware is executed when more than one route match is found.

Before Router Middlewares

Before route middlewares are route specific. Using a general route pattern (viz. all URLs), they can become Before Router Middlewares (in other projects sometimes referred to as before app middlewares) which are always executed, no matter what the requested URL is.

$router->before('GET', '/.*', function() {
    // ... this will always be executed
});

After Router Middleware / Run Callback

Run one (1) middleware function, name the After Router Middleware (in other projects sometimes referred to as after app middlewares) after the routing was processed. Just pass it along the $router->run() function. The run callback is route independent.

$router->run(function() { … });

Note: If the route handling function has exit()ed the run callback won't be run.

Overriding the request method

Use X-HTTP-Method-Override to override the HTTP Request Method. Only works when the original Request Method is POST. Allowed values for X-HTTP-Method-Override are PUT, DELETE, or PATCH.

Subfolder support

Out-of-the box bramus/router will run in any (sub)folder you place it into … no adjustments to your code are needed. You can freely move your entry script index.php around, and the router will automatically adapt itself to work relatively from the current folder's path by mounting all routes onto that basePath.

Say you have a server hosting the domain www.example.org using public_html/ as its document root, with this little entry script index.php:

$router->get('/', function() { echo 'Index'; });
$router->get('/hello', function() { echo 'Hello!'; });
  • If your were to place this file (along with its accompanying .htaccess file or the like) at the document root level (e.g. public_html/index.php), bramus/router will mount all routes onto the domain root (e.g. /) and thus respond to https://www.example.org/ and https://www.example.org/hello.

  • If you were to move this file (along with its accompanying .htaccess file or the like) into a subfolder (e.g. public_html/demo/index.php), bramus/router will mount all routes onto the current path (e.g. /demo) and thus repsond to https://www.example.org/demo and https://www.example.org/demo/hello. There's no need for $router->mount(…) in this case.

Disabling subfolder support

In case you don't want bramus/router to automatically adapt itself to the folder its being placed in, it's possible to manually override the basePath by calling setBasePath(). This is necessary in the (uncommon) situation where your entry script and your entry URLs are not tightly coupled (e.g. when the entry script is placed into a subfolder that does not need be part of the URLs it responds to).

// Override auto base path detection
$router->setBasePath('/');

$router->get('/', function() { echo 'Index'; });
$router->get('/hello', function() { echo 'Hello!'; });

$router->run();

If you were to place this file into a subfolder (e.g. public_html/some/sub/folder/index.php), it will still mount the routes onto the domain root (e.g. /) and thus respond to https://www.example.org/ and https://www.example.org/hello (given that your .htaccess file – placed at the document root level – rewrites requests to it)

Integration with other libraries

Integrate other libraries with bramus/router by making good use of the use keyword to pass dependencies into the handling functions.

$tpl = new \Acme\Template\Template();

$router->get('/', function() use ($tpl) {
    $tpl->load('home.tpl');
    $tpl->setdata(array(
        'name' => 'Bramus!'
    ));
});

$router->run(function() use ($tpl) {
    $tpl->display();
});

Given this structure it is still possible to manipulate the output from within the After Router Middleware

A note on working with PUT

There's no such thing as $_PUT in PHP. One must fake it:

$router->put('/movies/(\d+)', function($id) {

    // Fake $_PUT
    $_PUT  = array();
    parse_str(file_get_contents('php://input'), $_PUT);

    // ...

});

A note on making HEAD requests

When making HEAD requests all output will be buffered to prevent any content trickling into the response body, as defined in RFC2616 (Hypertext Transfer Protocol -- HTTP/1.1):

The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response. The metainformation contained in the HTTP headers in response to a HEAD request SHOULD be identical to the information sent in response to a GET request. This method can be used for obtaining metainformation about the entity implied by the request without transferring the entity-body itself. This method is often used for testing hypertext links for validity, accessibility, and recent modification.

To achieve this, bramus/router but will internally re-route HEAD requests to their equivalent GET request and automatically suppress all output.

Unit Testing & Code Coverage

bramus/router ships with unit tests using PHPUnit.

  • If PHPUnit is installed globally run phpunit to run the tests.

  • If PHPUnit is not installed globally, install it locally throuh composer by running composer install --dev. Run the tests themselves by calling vendor/bin/phpunit.

    The included composer.json will also install php-code-coverage which allows one to generate a Code Coverage Report. Run phpunit --coverage-html ./tests-report (XDebug required), a report will be placed into the tests-report subfolder.

Acknowledgements

bramus/router is inspired upon Klein, Ham, and JREAM/route . Whilst Klein provides lots of features it is not object oriented. Whilst Ham is Object Oriented, it's bad at separation of concerns as it also provides templating within the routing class. Whilst JREAM/route is a good starting point it is limited in what it does (only GET routes for example).

License

bramus/router is released under the MIT public license. See the enclosed LICENSE for details.

Comments
  • Multiple Changes on the Router Core

    Multiple Changes on the Router Core

    This Pull Requests adds more checks, performance gains and new features on the bramus/router package.

    New Features

    • Capability of Curly Braces as Pattern, like /home/{something}/and/{else}', actually they're converted unto\w+`
    • Capability of set a Default Namespace for Lookup on Callables Class@Method

    Checks

    • Sometimes getallheaders() is present but went unto problems and return false, now this is checked.
    • Now storing headers and method unto a property from Router and only first time usage updates it. (Observation.: For getRequestMethod added check if REQUEST_METHOD change, since phpunit overwrites it many times)
    • Other more checks.

    Each feature/change it's in a separate commit. Also created unit tests for each change.

    If the Pull Request gots approved, I will update the README.md with the new features.

    opened by ovflowd 15
  • Subfolder Detection not working properly

    Subfolder Detection not working properly

    Hi, I've installed this library thru Composer and it has been successfully loaded. I used the following code:

    /**
     * Routing System
     * @package bramus/router
     */
    $router = new \Bramus\Router\Router;
    
    $router->get('/', function() { echo "INDEX!<br>"; });
    $router->get('/test', function() { echo "HI<br>"; });
    $router->get('/hello', function() { echo "HELLO!!<br>"; });
    
    $router->run();
    
    echo "Done!";
    

    But no matter what my GET request is (to /, /test, /hello or even /asdf), it always shows "INDEX!"... Even copied and pasted the example (demo) code does not help at all! It just shows <h1>bramus/router</h1><....

    opened by PlanetTheCloud 13
  • CORS Edit

    CORS Edit

    This is not strictly relevant, but would be awesome to see when Googling for this problem. I would keep it here for visibility, but up to you. Thanks for this cool router!

    opened by TomGranot 12
  • Allow request URI and method to be overridden in the app

    Allow request URI and method to be overridden in the app

    I've added two new methods to override the request URI and method should it be required.

    setRequestMethodOverride()
    setRequestUriOverride()
    

    For my purpose, this allows me to specify a basic route in a query string of another pages request and pass that to the router. Don't ask! I also added the method override so the same can be done. My use case: index.php?page=api&method=POST&route=/movies. Isn't legacy software great!

    Issue #88 requested support for a _method field in POST forms, this PR will allow users to integrate that in their app without breaking compatibility with existing installations.

    I've added three tests with several assertions and to ensure the server side overrides take precedent over X-HTTP-Method-Override (as if the developer feels the need to use the new methods, that header should be disregarded, the developer is still free to use it in their own method determination logic).

    The README and demo's have also been updated.

    Thanks for the great router, I hope this can help someone!

    opened by mewejo 10
  • How to access Parameters from route

    How to access Parameters from route

    Am kinda lost even after going through the examples and description page multiple times.

    If I have a url in this format -> http://example.com/properties/for-sale/canada/condo/3-bed-room-duplex. I can easily route the above url to the correct controller which would match the request uri and display the page for http://example.com/properties/for-sale/canada/condo/3-bed-room-duplex BUT how do i extract these parameters 'for-sale', 'canada', 'condo', '3-bed-room-duplex'

    Let's assume I used the $router->get() function.

    Have gone through the codes and can see where the parameters called ₦params exists but without having to modify the class, need to know if I already can access those values without knowing.

    This is to avoid modifying a code whose function I want to implement already exists.

    Thanks

    opened by kezenwa 10
  • Problem with dynamic routes and mount

    Problem with dynamic routes and mount

    Hi,

    I tried searching but I did not get the issue / solution. Not sure if this is reported. Here is the problem I am facing, I am creating a reddit sort of url scheme.

    URL Structure needed:

    
    / -> Homepage
    /{category_url}/ -> show category posts
    /{category_url}/view/{post_url} -> show post within category.
    
    
    

    I can do that in multiple routes but I am trying to use subrouting / Mounting Routes:

    Here is the code:

    
    $router->mount('/{category_url}', function($category_url) use ($router) {
    
        $router->get('/', function() use($category_url) {
            echo "Show Category: ".$category_url;
        });
    
        $router->get('/view/{post_url}', function($post_url) use($category_url) {
            echo "Show post: ".$post_url." in category" .$category_url;
        });
    
    });
    
    

    even this is not working:

    $router->get('/{category_url}',function($category_url){
        echo "Show Category: ".$category_url;
    });
    
    $router->get('/{category_url}/view/{post_url}', function($category_url, $post_url) use($router) {
        echo "Show post: ".$post_url." in category" .$category_url;
    });
    
    
    

    I feel I am doing something wrong rather than this being an "issue" with the router. However, clarification from the community would be great.

    opened by iKevinShah 10
  • Cyrillics issue

    Cyrillics issue

    Hi guys,

    I have a website with Cyrillic text slugs. For example: domain.com/bg/това-е-слъг Currently the router does not work on Cyrillic text. So I had to change your code in Route.php, 341row:

    $route['pattern'] = preg_replace('/{([A-Za-z]*?)}/', '(\w+)', $route['pattern']);

    to

    $route['pattern'] = preg_replace('/{([A-Za-zа-яА-Я]*?)}/', '(\w+)', $route['pattern']);

    I hate changing original code and it's not the best solution, so maybe you can do something about the cyrillics in the next push.

    Thank you!

    bug good first issue 
    opened by notom 10
  • $_POST problem

    $_POST problem

    $_POST is not working. I can't retrieve post variable with that or not even $_REQUEST. $router->post('/', function () { ; }); Let me know, how to detect post variables? Like if I wanna get the value of $_POST['Key'] or wanna see all the key, value of $_POST; what to do?

    opened by abmmhasan 10
  • support to set up a default constructor params for Class@Method calls

    support to set up a default constructor params for Class@Method calls

    I needed this to my projects in a way to extend the Class@Method calls.

    This is an example, in my bootstrap.php:

    $log = get_logger();
    $tpl = get_templates();
    
    $router = new \Bramus\Router\Router();
    $router->setNamespace('App\Controller');
    $router->setConstructorDefaults($tpl, $log);
    
    $router->get('/', 'Root@index');
    
    $router->run();
    

    Then, in my Base controller I have something like...

    class Base {
    	protected $tpl;
    	protected $log;
    
    	public function __construct(\League\Plates\Engine $template, \Monolog\Logger $logger) {
    		$this->tpl = $template;
    		$this->log = $logger;
    	}
    }
    

    And in the Root controller...

    class Root extends Base {
    	public function index() {
    		$this->log->info("test");
    		echo $this->tpl->render('index');
    	}
    }
    

    Thank you for your work!

    opened by xergio 9
  • Troubleshooting non-matches ?

    Troubleshooting non-matches ?

    Hi,

    I'm really struggling to get bramus/router to work on my setup (NGINX + PHP7), I have no problems at all with aura/router, but nothing I do seems to get bramus to match ! The only reason I'm being forced to use bramus is because of your support for "before" which aura doesn't.

    What is the recommended methodology to troubleshoot the route matching process ? The bramus docs seem to make no mention of this, they simply assume everything "just works".

    Thanks !

    opened by udf2457 9
  • Regulation start from N segment

    Regulation start from N segment

    Need discussion about using this class in multilingual site, assumed domain.com will be redirect to domain.com/en (in english) and domain.com/id (in indonesia)

    // domain.com/en/ or domain.com/id/
    define('DOMAIN', app('domain') . '/' . Session::get('language', app('language')) . '/');
    
    // detect segment
    function segment($segment = null)
    {
        $path = implode('/', array_slice(explode('/', $_SERVER['SCRIPT_NAME']), 0, -1)) . '/';
        $uri = mb_substr($_SERVER['REQUEST_URI'], mb_strlen($path));
    
        $trim = trim($uri, '/');
        $data = mb_strpos($trim, '/') ? explode('/', $trim) : [$trim];
    
        if (is_null($segment)) {
            return $data;
        }
    
        return $segment <= count($data) ? $data[$segment - 1] : '';
    }
    
    // print_r(segment()); : domain.com/en/title -> array([0] => en [1] => title)
    
    
    $router = new \Bramus\Router\Router();
    
    // before route middleware
    $router->before('GET', '/(.*)', function($slug) {
        if (in_array(segment(1), ['en', 'id'])) {
            Session::set('language', segment(1));
        } else {
            redirect(DOMAIN . $slug);
        }
    });
    
    $router->all('/(.*)', function($slug) {
        echo $slug;
    });
    

    When i call domain.com/en/title, i expect $slug = 'title'; not $slug = 'en';

    Actually using $router->mount($baseroute, $fn) this issue completed

    $router->mount('/'. segment(1), function() use ($router) {
        $router->all('/(.*)', function($slug) {
            echo $slug;
        });
    });
    

    But i looking for some regulation to start from N segment, something like $route->startfromsegment = 1;

    Any other idea ? or mount a collection is a right way ?

    opened by ncaneldiee 9
  • $route->set404 = redirect to ?uri= if folder exist

    $route->set404 = redirect to ?uri= if folder exist

    Hi, I want to return a 404 error page for all request starting with WEB_INF like http: //domain.com/WEB-INF Is it normal behavior that url is redirected to http: //domain.com/WEB-INF?uri=WEB-INF. Please note that WEB-INF folder really exist on my serverRoot and below rule works fine if folder doesn't exist...

    $router->set404('/WEB_INF(/.*)?', function () {
        require '/404.php';
    });
    

    Thanks

    opened by hroma 0
  • Unhandled notice exception instead of 404 handling

    Unhandled notice exception instead of 404 handling

    Notice: this issue is applicable for any HTTP method. Lets use PUT for example. The Router throws 'Undefined index: PUT' PHP notice when there is attempt to call PUT method, and no PUT routers were registered. Snipet to reproduce:

    $router = new \Bramus\Router\Router();
    $router->set404(function(){
        echo 'Not found';
    });
    $router->run();
    

    Expected: 404 handler triggered without PHP notices. Actual: PHP notice

    opened by idashevskii 4
  • Support to catch reflection fail on controller method call from outsi…

    Support to catch reflection fail on controller method call from outsi…

    …de the Router. Fixed missing class Handler (due to failed test after adding support for the former catching).

    According to requested feature #185 https://github.com/bramus/router/issues/185

    I hope it fulfills the feature accordingly.

    opened by xnan-dev 0
  • Show if class or method does not exists

    Show if class or method does not exists

    I'm Using the Router and extending it in my own class in order to change some methods and update the router without loosing changes. The invoke() method is private and I need to catch if no Class or method exists and return it. I found that there is a catch of The ReflectionException in invoke() method, and I think that's exactly what I need but it's a private and I cannot override it. Is there another way to return message that a class or method does not exists, because now it shows an white screen, when the name of the class or method is wrong.

    good first issue feature request 
    opened by givanov95 3
Owner
Bramus!
JS / React Dev with a love for CSS and a background in PHP. Former University Lecturer "Web & Mobile". PADI Divemaster.
Bramus!
PhpRouter is a powerful, lightweight, and very fast HTTP URL router for PHP projects.

PhpRouter PhpRouter is a powerful, lightweight, and very fast HTTP URL router for PHP projects. Some of the provided features: Route parameters Predef

Milad Rahimi 152 Dec 28, 2022
A lightweight and fast router for PHP

Piko Router A lightweight and blazing fast router (see benchmarks) using a radix trie to store dynamic routes. This router maps routes to user defined

Piko framework 62 Dec 27, 2022
A lightweight and very basic PHP router.

Katya A lightweight PHP router Configuration Para servidor Apache, en el directorio del proyecto crea y edita un archivo .htaccess con lo siguiente: <

Luis Rodríguez 0 Apr 4, 2022
Simple, fast and yet powerful PHP router that is easy to get integrated and in any project.

Simple, fast and yet powerful PHP router that is easy to get integrated and in any project. Heavily inspired by the way Laravel handles routing, with both simplicity and expand-ability in mind.

Simon Sessingø 472 Jan 4, 2023
:bird: Simple PHP router

Macaw Macaw is a simple, open source PHP router. It's super small (~150 LOC), fast, and has some great annotated source code. This class allows you to

Noah Buscher 895 Dec 21, 2022
Flight routing is a simple, fast PHP router that is easy to get integrated with other routers.

The PHP HTTP Flight Router divineniiquaye/flight-routing is a HTTP router for PHP 7.1+ based on PSR-7 and PSR-15 with support for annotations, created

Divine Niiquaye Ibok 16 Nov 1, 2022
A simple PHP Router

Panda Router Description the panda-router is a small alternative PHP router that can be used for small projects. With this router you can use differen

Jan Behrens 1 Dec 27, 2021
The simple PHP router

Macaw Macaw is a simple, open source PHP router. It's super small (~150 LOC), fast, and has some great annotated source code. This class allows you to

Noah Buscher 895 Dec 21, 2022
:tada: Release 2.0 is released! Very fast HTTP router for PHP 7.1+ (incl. PHP8 with attributes) based on PSR-7 and PSR-15 with support for annotations and OpenApi (Swagger)

HTTP router for PHP 7.1+ (incl. PHP 8 with attributes) based on PSR-7 and PSR-15 with support for annotations and OpenApi (Swagger) Installation compo

Sunrise // PHP 151 Jan 5, 2023
Pux is a fast PHP Router and includes out-of-box controller tools

Pux Pux is a faster PHP router, it also includes out-of-box controller helpers. 2.0.x Branch Build Status (This branch is under development) Benchmark

Yo-An Lin 1.3k Dec 21, 2022
Toro is a PHP router for developing RESTful web applications and APIs.

Toro Toro is a PHP router for developing RESTful web applications and APIs. It is designed for minimalists who want to get work done. Quick Links Offi

Kunal Anand 1.2k Dec 27, 2022
Thruway - an open source client and router implementation of WAMP (Web Application Messaging Protocol), for PHP.

PHP Client and Router Library for Autobahn and WAMP (Web Application Messaging Protocol) for Real-Time Application Messaging

Voryx 661 Nov 14, 2022
PHPRouter is an easy-to-use, fast, and flexible PHP router package with express-style routing.

PHP-Router is a modern, fast, and adaptable composer package that provides express-style routing in PHP without a framework.

Ayodeji O. 4 Oct 20, 2022
klein.php is a fast & flexible router for PHP 5.3+

Klein.php klein.php is a fast & flexible router for PHP 5.3+ Flexible regular expression routing (inspired by Sinatra) A set of boilerplate methods fo

null 2.6k Jan 7, 2023
OpenAPI (Swagger) Specification Support for Sunrise Router (and not only)

OpenAPI (Swagger) Specification Support for Sunrise Router Important to understanding OpenAPI Specification Installation composer require 'sunrise/htt

Sunrise // PHP 3 Feb 12, 2022
Fast request router for PHP

FastRoute - Fast request router for PHP This library provides a fast implementation of a regular expression based router. Blog post explaining how the

Nikita Popov 4.7k Dec 23, 2022
A web router implementation for PHP.

Aura.Router Powerful, flexible web routing for PSR-7 requests. Installation and Autoloading This package is installable and PSR-4 autoloadable via Com

Aura for PHP 469 Jan 1, 2023
A PHP Router Package

Router A PHP Router Package Basic Concepts A router package is a utility that, once all http requests are redirected to an entry point, can configure

null 0 Aug 26, 2022
A fast & flexible router

Klein.php klein.php is a fast & flexible router for PHP 5.3+ Flexible regular expression routing (inspired by Sinatra) A set of boilerplate methods fo

null 2.6k Dec 28, 2022