zelasli / routing
Zelasli Routing module that link single HTTP request to a controller actions.
Requires
- php: ^8.1.0
README
A routing module that link single HTTP request to a destination (controller's action)
Installation
To install using composer in your project (recommended
):
composer require zelasli/routing
You can also clone the repository and include all the files resides inside src/
to the entry point of your project.
git clone https://github.com/zelasli/routing.git
and includes the modules files
require_once 'path/to/src/Placeholders.php'; require_once 'path/to/src/Route.php'; require_once 'path/to/src/RouteBuilder.php'; require_once 'path/to/src/RouteCollection.php'; require_once 'path/to/src/Router.php';
Getting started
Create the RouteBuilder
which will build the linking of the URL
to the given destination.
$routeBuilder = new RouteBuilder(new RouteCollection);
Defining the linking
Define all your request linking and grouped linking to a prefix initial. The link is a method in the RouteBuilder
that create Route
for the request url and link that request URL to destination of an action. This action comprises of class namespace and method to be invoked, with it's parameter(s) to pass.
The first parameter define the URL that will match the linking (Route
), and the second parameter is the class namespace with action, and parameter to be extracted from the very first parameter.
$builder->link('/home', 'HomeController::index')
The above linking can also be defined like this which the second parameter to be an array of the controller class and action (the class method to invoke).
$builder->link('/home', ["HomeController", "index"]);
Linking with parameters
The linking can also collect parameters to pass when invoking a controller's action.
$builder->link('/blogs/(:digit)', "App\\Controllers\\BlogController::view/{1}");
This means that the matching of /blogs/123456789
will extract the value 123456789
as a number and it means that the method view
in class App\Controllers\BlogController
has a parameter that collect integer value.
You can also use name of parameter like this
$builder->link('/blogs/(blogId:digit)', "App\\Controllers\\BlogController::view/{blogId}");
Linking with name
A linking can also have a name used to reverse the route
$builder->link('/blogs/(blogId:digit)', "App\\Controllers\\BlogController::view/{blogId}", [ 'name' => 'blogViewPage' ]);
Grouping related linking
You can also group related linking with the same initial.
$builder->group('/blogs', function (RouteBuilder $builder) { $builder->link('/', "App\\Controllers\\BlogController::view_all", [ 'name' => 'blogsViewAll' ]); $builder->link('/create', "App\\Controllers\\BlogController::create", [ 'name' => 'blogsCreate' ]); $builder->link('/view/(blogId:digit)', "App\\Controllers\\BlogController::view/{blogId}", [ 'name' => 'blogsView' ]); $builder->link('/delete/(blogId:digit)', "App\\Controllers\\BlogController::delete/{blogId}", [ 'name' => 'blogsDelete' ]); $builder->link('/update/(blogId:digit)', "App\\Controllers\\BlogController::update/{blogId}", [ 'name' => 'blogsUpdate' ]); });
Working with Router
The main use of Router
is to find the Route
that matches the current HTTP request url. Now, get the instance of Router
object from the builder.
$router = $routeBuilder->getRouterInstance();
Find the matched Route
Here you will ask Router
to give you a Route
that match the specifier you give.
$url = parse_url($_SERVER['REQUEST_URI']); // use parse_url() because query string may have been exists $route = $router->findRouteByUrl($url['path']);
If a client request goes like this: http:://example.com/blogs/view/123456789
then the Router
will search in the collection and find the matched Route
instance. Now get the the class and it's method
// http:://example.com/blog/123456789 $class = $route->getClass(); // App\Controllers\BlogController $action = $route->getAction(); // view $params = $route->getParams(); // [blogId => 1282]
Get them ready to invoke the action (method)
$obj = new $class(); // $obj = new App\Controllers\BlogController(); $obj->{$action}(...$params); // $obj->view(...[blogId => 1282])
Reverse URL
The Router
can also reverse URL
string of a named linking (Route
) using Router::reverseUrl
$router->reverseUrl('blogsView', [ 'blogId' => 1234 ]); // return: /blogs/view/1234
You can also define you own placeholder types using the Router::registerPlaceholder
function.
Router::registerPlaceholder('date', '\d{4}\/\d{1,2}\/\d{1,2}', false);
The fisrt parameter passed is the name of type, the second is pattern, and the third is a boolean whether your defined type can have quantifier or not, the default is true. Then use it the way you are using types
$builder->link('/blog/(d:date)/(id:digit)', 'App\\Blog\\Post::view/{date}/{id}');
The above type will match the request: http://example.com/blog/2006/3/21/1234
. This will extract 2006/3/21
as $d
and 1234
as $id
.
Route
As we already see we use builder->link($url, $destination, $options)
to create new Route that link the $url
to the $destination
with optional parameter $options
. Here we go deep into it.
Route URL
The first parameter $url
in RouteBuilder::link
can contains placeholders to be extracted called variable arguments which can be passed to class method as it's parameters. This placeholder's rule syntax look like:
([name][:type][:quantifier])
[name] - Optional. The name of parameter for this placeholder
[:type] - The type of value this placeholder can hold.
[:quantifier] - Optional. The length of the value.
The second parameter is the destination of the request URL that Route
map to. Which contains a class and it's method with parameters given according to the order they are written in that method.
Route Types
These are the list of valid placeholder types defined.
For the placeholder that can have quantifier, this is the format they can be written.