PHPRouter is an easy-to-use, fast, and flexible PHP router package with express-style routing.

Overview

PHP Router

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

This website is powered by this package -> View site

Installation

composer require trulyao/php-router

Create a new dockerized PHP project (contains MySQL, Apache2, PHPMyAdmin) that uses this package by running this Composer command:

composer create-project trulyao/php-starter hello-world

Update .htaccess file

This is very important to get the router working correctly.

Warning: Depending on your Apache configuration, some headers will not be allowed to come through to your application, this has nothing to do with this package, you just need to enable them in your Apache configuration.

Options +FollowSymLinks
RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteCond %{REQUEST_URI} !=/index.php
RewriteCond %{REQUEST_URI} !.*\.png$ [NC]
RewriteCond %{REQUEST_URI} !.*\.jpg$ [NC]
RewriteCond %{REQUEST_URI} !.*\.css$ [NC]
RewriteCond %{REQUEST_URI} !.*\.gif$ [NC]
RewriteCond %{REQUEST_URI} !.*\.js$ [NC]
RewriteRule .* /index.php
RewriteRule .* - [E=HTTP_CONTENT_TYPE:%{HTTP:Content-Type},L]
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]

Features

  • Open source
  • Fast and easy-to-use syntax
  • Provides request and response objects
  • Supports dynamic routing like /:id or /:id/:name
  • Supports 4 major HTTP methods (GET, POST, PUT, DELETE)
  • Uses callbacks to handle requests
  • Supports custom 404 and 500 error pages
  • Supports redirection
  • Serves static files, JSON and more
  • Helper functions for common tasks like sending JSON, setting status codes etc.
  • Function and class based controller and middleware support

Usage

index.php

get("/", function($req, $res) { return $res->send("

Hello World

") ->status(200); }); $router->get('/render', function ($req, $res) { return $res->render("second.html", $req); }); $router->post("/", function($req, $res) { return $res->send([ "message" => "Hello World" ]); }); # using a class based controller $router->delete("/", [new NoteController(), "destroy"]); $router->route("/chained") ->get(function ($req, $res) { return $res->send("GET - Chained!"); }) ->post(function ($req, $res) { return $res->send("POST - Chained!"); }); # Start the router - very important! $router->serve(); ?>">


use \Trulyao\PhpRouter\Router as Router;

$router = new Router(__DIR__."/views", "demo");

$router->get("/", function($req, $res) {
    return $res->send("

Hello World

") ->status(200); }); $router->get('/render', function ($req, $res) { return $res->render("second.html", $req); }); $router->post("/", function($req, $res) { return $res->send([ "message" => "Hello World" ]); }); # using a class based controller $router->delete("/", [new NoteController(), "destroy"]); $router->route("/chained") ->get(function ($req, $res) { return $res->send("GET - Chained!"); }) ->post(function ($req, $res) { return $res->send("POST - Chained!"); }); # Start the router - very important! $router->serve(); ?>

/views - The directory where your views/controllers/source files are located.

/demo - This is the base URL for your application eg. api for /api/* or v1 for /v1/*.

The $req object

The $req object contains the request data, it also has helper methods for accessing this data.

  • query("name") - Returns the query string value for the given name or all query string values if no name is given.

  • body("name") - Returns the body value for the given name or all body values if no name is given.

  • params("name") - Returns the params value for the given name or all file values if no name is given.

  • path() - Get current full request path.

  • headers() - Get all request headers.

  • header("name") - Get a single request header value.

  • append($key, $value) - Append data to the request object.

  • data - The data array for the request object (useful for passing data to the middleware and callback functions).

Note: The $req object is passed to all middleware and callback functions. If you use any of the response methods like send(), the middleware will not move on to the next one.

The $res object

The $res object is used to control the response and holds data related to responses and just like the request object, it has methods you can use.

  • error($message, $status) - Send a JSON error response.
  • send($data) - Send a JSON/HTML response; automatically detected.
  • json($data) - Send a JSON response.
  • render($file) - Render a view with the built-in mini template engine, you can also pass in your own data.
  • redirect($path) - Redirect to another path - eg. /example/login
  • status($status) - Set the status code (defaults to 200, optional)
  • use_engine() - Enable and use the built-in mini template engine for rendering views.

More methods will also be added in the future.

You can access these any functions outside your index or main file too by using the namespace Trulyao\PhpRouter\HTTP. Also, you are not constrained to any particular coding style or variable naming convention either.

Error Pages

You can easily add a custom 404, 405 or 500 page by creating a file in the /views directory (or wherever your base path is; where your controllers or views are) called 404.php, 405.php or 500.php

Views & Templates

In views, you are provided with the following variables by default:

  • query - The query string values.
  • body - The request body values.
  • params - The request params values.
  • headers - The request headers.
  • data - User-defined data eg. current user from JWT
  • root_dir - The current request path.

Note: headers are made case-insensitive while accessing them in views. This package also comes with a templating engine that is turned off by default, you can enable or disable it by passing a boolean value to the render method. This templating engine is still experimental and does not support a lot of features yet. Check this file for an example of how to use it.

You can use any of these variables in a PHP view file by using $query['field_name'], $data['field_name'] etc or in a template file (most likely html) by using the directives like @query('field_name'), @body().

Components and Raw Code

You can execute some PHP codes in views by using the @php ... @endphp directives. This is quite limited and useful for codes that don't echo anything like the session_start() function as all the output is at the top of the view file.

@php
    session_start();
@endphp

You can also use the @component directive to include a component file.

@component('component.html')

For more examples, check out the examples directory. If you have forked and/or cloned this repo; to start the test server, run composer run start:dev, the base URL is http://localhost:20000/demo. Here are all the available endpoints:

  • [GET] /
  • [GET] /render
  • [GET] /render/middleware
  • [GET] /json
  • [GET] /dynamic/:id
  • [GET] /dynamic/:id/nested
  • [GET] /dynamic/:id/:name
  • [GET] /middleware
  • [GET] /redirect
  • [POST] /:id
  • [PUT] /:id
  • [DELETE] /:id
  • [GET | POST | PUT | DELETE] /chained

Contribute

  • Fork the repository on GitHub
  • Add your own code
  • Create a pull request with your changes highlighted
  • For more information, contact me here

This documentation will be updated as soon as new features and methods are added to the package.

Warning: PHP, like a lot of other languages, runs from top to bottom, to avoid conflicts, put your chained routes at the bottom of the file; it is still fairly unstable and may override your dynamic routes eg. putting /chained which is a chained route before /:id for a GET request will only direct you to the /chained route because it technically matches the latter.

You might also like...
A lightweight and fast router for PHP
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

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

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

πŸ” This is a collection of utilities for routing and loading components.
πŸ” This is a collection of utilities for routing and loading components.

Router Utilities - PHP Introduction A day will come when I will write documentation for this library. Until then, you can use this library to create r

Generate a PHP script for faster routing :rocket:
Generate a PHP script for faster routing :rocket:

SwitchRoute Generating a PHP script for faster routing. The traditional way of routing uses regular expressions. This method was improved by FastRoute

Convention based routing for PHP

Croute Convention based routing for PHP based on Symfony components. Croute is great because: You don't need to maintain a routing table Promotes cons

PHP routing (like laravel) (not complete yet)

PHP Router (under construction) This repository contains routing classes that enables you to define your routes similar to laravel 8 routes. Features

Ertuo: quick routing for PHP

Ertuo: quick routing for PHP Ertuo (anagram of "Route"), is a small PHP library that does routing better and faster than conventional regular expressi

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

Comments
  • adding multiple routing using a single path

    adding multiple routing using a single path

    Just like express.js router this is to add multiple routing methods for a single route path just like

    #multiple route 
    $router->route('/hello')
        ->get(function($req, $res) {
            return $res->send("<h1>Hello World</h1>")->status(200); // sends html response
        })
        ->post(function($req, $res) {
            return $res->send([
                "message" => "Hello World posted"
            ])->status(200); // sends json response
        });
    

    instead of

    # GET route
    $router->get("/hello", function($req, $res) {
        return $res->send("<h1>Hello World</h1>")->status(200); // sends html response
    });
    
    # POST route
    $router->post("/hello", function($req, $res) {
       return $res->send([
                "message" => "Hello World posted"
            ])->status(200); // sends json response
    });
    
    opened by codad5 2
  • Added a sub route method to merge multipy router object

    Added a sub route method to merge multipy router object

    During the course of working with a great library, i began to get frustrated due to the messy code caused by setting the routes so

    Thing I tried :

    • Using include / require πŸ‘Ž This worked fine until I ran into a variable naming clash, a variable already declared in my index.php was overwritten by the same variable in the included /required class

    example index.php

    require(__DIR__ . '/../vendor/autoload.php');
    use My\Namesapce\AClass;
    use Trulyao\PhpRouter\Router as Router;
    $router = new Router(__DIR__ . "/views", "");
    $somevariable = new AClass('special_id');
    $router->get('/something', ...)'
    include_once 'routes\to.php';
    

    routes\to.php

    //some reason to create another object of the AClas
    use My\Namesapce\AClass;
    $somevariable = new AClass('special_id_2');
    $router->get('/depth/something', ...);
    

    Then I came up with the use_route method but still these, errors above After which i made a library that made everything work

    you can check it out in examples/index.php

    Thanks

    opened by codad5 1
  • A new request method

    A new request method

    I think there should be a new request method to check if the request is from the same host to prevent a case where someone from https://anything.com is trying to send a forged post request to the route on the website.

    Something like

    $router->post('signup', function ($req, $res) {
    $req-isFriendly();
    });
    

    I also think it should be a static method so that it can be initialised at the beginning of our script so it can be possible to work for all routes instead of recalling the method in all the routes.

    I think there should also be a setter method to add a list of friendly hosts in case the website might be making use of multiple hosts like api.this.com, payment.this.com or any other of your parent domain which could act like unfriendly hosts.

    This could help increase security and reduce bad codes by developer

    final example code for single route

    $router->set_friendly_host('API.domain.com', 'myoldproject.com', 'version1.com');
    
    $router->post('/payment', function($req, $res){
      If(!$req->isFriendly()){
           $res->status(400)->json(['message' => 'Cannot post from such URL to this route']);
      }
     #... More code
    });
    

    final code for multiple routes

    $router = new Router();
    $router->set_friendly_host('API.domain.com', 'myoldproject.com', 'version1.com');
    
    $router-must_be_friendly(function($req, $res){
      $res->status(400)->json(['message' => 'Cannot post from such URL to this route']);
    });
    
    $router->post('/payment', function($req, $res){
     #... More code
    });
    
    
    opened by codad5 1
Releases(2.0.5)
  • 2.0.0(Aug 19, 2022)

    • This is a major breaking update
    • Switched to PHP 7.4 for type declaration compatibility
    • Added PHPDoc for contributors and users
    • Added "template" engine for views
    • Added support for route chaining via the ->route() method (experimental)
    • Refactored and improved code - SnakeCase is used for uniformity and improved readability
    • render has now replaced the Response class method use with support for data and template variables
    • The Helper sub-namespace is now HTTP.
    • Added (multi-layer) middleware support for all verbs/methods
    • Added support for custom 405 error page
    • Added support for components that have access to the data tree using the @component() directive
    • Added the append method to the request object to allow for appending of data to the request object for use in the middleware functions
    • Added the data array to serve as a custom data store in the request object

    Full Changelog: https://github.com/aosasona/php-router/blob/main/CHANGELOG.md

    Source code(tar.gz)
    Source code(zip)
  • 1.0.3(Aug 14, 2022)

    • Fixed routing issue with empty base URL (where it wouldn't create routes if there is an empty base URL and a slash)
    • Fixed status helper issue (where it wouldn't set the response if it was not chained on before the response body)
    • Improved helper functions security
    Source code(tar.gz)
    Source code(zip)
  • v1.0.2(Jul 30, 2022)

Owner
Ayodeji O.
Building, learning, iterating & improving πŸ‘¨πŸ»β€πŸ’»
Ayodeji O.
PHP routing class. Lightweight yet flexible. Supports REST, dynamic and reversed routing.

AltoRouter AltoRouter is a small but powerful routing class, heavily inspired by klein.php. $router = new AltoRouter(); // map homepage $router->map(

Danny van Kooten 1.1k Jan 3, 2023
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
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
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
Routing - The Routing component maps an HTTP request to a set of configuration variables.

Routing Component The Routing component maps an HTTP request to a set of configuration variables. Getting Started $ composer require symfony/routing

Symfony 7.3k Jan 6, 2023
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
PHP Router class - A simple Rails inspired PHP router class.

PHP Router class A simple Rails inspired PHP router class. Usage of different HTTP Methods REST / Resourceful routing Reversed routing using named rou

Danny van Kooten 565 Jan 8, 2023
Fast PSR-7 based routing and dispatch component including PSR-15 middleware, built on top of FastRoute.

Route This package is compliant with PSR-1, PSR-2, PSR-4, PSR-7, PSR-11 and PSR-15. If you notice compliance oversights, please send a patch via pull

The League of Extraordinary Packages 608 Dec 30, 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