Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 

Repository files navigation

PHP - Router

A Small PHP-Lib providing Controller based Routing via PHP. Controllers and Routes are defined via Attributes.

Installation

Just copy the Router.php of this Repo into your project and include it.

Usage

The ìndex.php

Usually, this is the entrypoint to your application, and the first PHP-Script to be executed.

<?php
    require_once __DIR__ . "/Router.php";

    use rogoss\router\Router;

    (new Router(

        // Folder, where the Router will search for suitable Controllers and Routes
        __DIR__ . "/controllers",

        // The Default Controller, used to handle all calles to the domain
        __DIR__ . "/controllers/_.php",

        // if the given URL is not handled by a Controller, the Router will search this DIR for the
        // requested URL
        __DIR__ . "/static_content",

        // Should the content not be found in the "static_content" folder either,
        // a 404 response is given

    ))->HandleRoute($_SERVER['REMOTE_URI']);

The /controllers Folder

This router handles SubDirectories as controllers

The controller is defined by the first Subdirectory of the url. So you need to keep directory name limitations in mind, when defining your URLs

Example:

GET office/index.hml => __DIR__ . "/controllers/office.php"
GET kitchen/coffemachine => __DIR__ . "/controllers/kitchen.php"
GET kitchen/coffemachine/coffee.html => __DIR__ . "/controllers/kitchen.php"

The /controllers/_.php File

If the requested URL does not contain a directory, the request will be handled by the Controller defined in this file.

Defining Controllers

As the already described, the Router uses the first directory of a URL to define the controller-file. Inside that file a Class with the Attribute #[RouterController] should be part of this File.

Inside that class, you define static methods that have one or more RouterRoute Attributes.

a basic controller file could look like this.

<?php
    // `__DIR__ . "/controllers/kitchen.php"
    require_once __DIR__ . "/../Router.php";

    use rogoss\router\RouterController;
    use rogoss\router\RouterRoute;

    #[RouterController]
    class KitchenController {

        #[
            RouterRoute(""),  // calls to `/kitchen/`
            RouterRoute("index.html") // calls to `/kitchen/index.hml`
        ]
        public static function indexPage() {

            echo "<h1>Welcome to the Kitchen</h1>",
                "<br />",
                "<a href=\"coffeemachine/coffee.html\">",
                "Time for Coffee !!!",
                "</a>"
            ;

        }

        #[ RouterRoute("coffeemachine/coffee.html") ]
        public static function coffeemachineCoffeePage() {

            // this name does not matter, ----/\
            // because Attributes, but you may choose something, that
            // makes it easier to find for your editor

            echo "<h1>Coffeemachine => choose </h1>",
                "<br /> <a href=\"coffemachine/coffee/black\">Black</a>",
                "<br /> <a href=\"coffemachine/coffee/milk\">Milk</a>",
            ;

        }

    }

Warning

Since the first found directory identfies the controller, you can't invoke the controller by it's name alone.

lets take GET /kitchen as an example. You would want this to be handled by __DIR__ . "/controllers/kitchen.php" => RouterRoute("")

However, there is no directory in the URL /kitchen, while there is one in /kitchen/. /kitchen (without trailing /) will be handled by _.php (the default controller) instead.

Defining Routes

Routes are static class functions identified by the #[RouterRoute] Attribute.

RouterMethods are given at least 2 Parameters.

// A reference to the Router that is currently processing the Request
Router $router

// An array, containing matched route and, for expression-routed, the matched capture groups
string[] $matches

We can use these two to solve the problem, that routers can't be invoked by semselfs without a trailing / in the url

in _.php (the default controller) define a route method, that redirects a call to office and kitchen to their office/ and kitchen/ counterparts.

<?php
// ...
    #[
        RouterRoute("office"),
        RouterRoute("kitchen")
    ]
    public static function redirectToControllerRoot(
        Router $router,  // the parameters of the function are identified by name
        array $matches   // therefor, you must define your parameters like this.
                         // but the advantage of this is, that you only need to define the parameters,
                         // that you actively use.
    ) {
        $router->HandleRoute("{$matches[0]}/"); // <- matches[0] is always the full matched path, notice that we add "/" to the end.
                                                // A slash marks that we target the controller, rather than a route
    }

Defining Expression Routes

It is possible to define more dynamic routes, by using regular expressions.

<?php
//...
    #[
        RouterRoute( expression: "office-([0-9]+)" ),
    ]
    public static function redirectOfficeRoute(
        array $matches  // as mentioned in the example of the basic route.
                        // the router used named parameters to call the route.
                        // since this function doesn't need the router, we can
                        // just define the $matches parameter and thus
                        // don't need to worry about the LSP, nagging about "unused parameters"
    ) {
        $officeid = $matches[1];
        // do something with the retreived $officeid
    }

The above RouterRoute would match any route containing the word office, followed by a dash and a number:

office-1
...
office-34
...
office-99
...

we can extract that number through the $matches Paramter, given to the Route Handler. Since expression routes follow RegularExpression / preg_match rules, and we put the number-match in parentheses ([0-9]+),

About

A Small PHP based Router using PHP 8.x Attributes

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages