2017 © Pedro Peláez
 

library easyroute

Very lightweight and simple router for PHP

image

iassasin/easyroute

Very lightweight and simple router for PHP

  • Wednesday, February 14, 2018
  • by iassasin
  • Repository
  • 0 Watchers
  • 0 Stars
  • 37 Installations
  • PHP
  • 0 Dependents
  • 0 Suggesters
  • 0 Forks
  • 2 Open issues
  • 11 Versions
  • 0 % Grown

The README.md

Easyroute

PHP Version Build Status Coverage Status, (*1)

Simple router do not require a lot of setups, install in few minutes and just works., (*2)

Installation

To start using router complete 4 simple steps:, (*3)

  1. Install easyroute via composer:
composer require iassasin/easyroute
  1. Setup yours routes in root directory of project. For example in file routes.php:
require_once 'vendor/autoload.php';
use Iassasin\Easyroute\Router;
use Iassasin\Easyroute\Route;

$router = new Router();
$router->setControllersPath($_SERVER['DOCUMENT_ROOT'].'/controllers/');
$router->addRoutes([
    new Route('/(:controller:(/:action:(/:arg)?)?)?', ['controller' => 'home', 'action' => 'index', 'arg' => null]),
]);
$router->processRoute();
  1. Tell web server redirect all requests (except static assets/) to router via .htaccess:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/assets/
RewriteRule ^(.*)$ routes.php [B,QSA,L]
  1. Create first controller in controllers/home.php:
class ControllerHome {
    public function index($arg){
        return '<html><body>Home page! '.($arg !== null ? 'Argument: '.$arg : 'Argument not set').'</body></html>';
        // or use "return new Response('...')" which is more flexible
    }
}

That's it!, (*4)

Note that file name must match :controller name from URL template and controller class name must match :controller name with prefix Controller. In example above route /home/index matches file controllers/home.php and class ControllerHome., (*5)

Useful features

Route with parameters

Route is a regex string with simpler syntax for naming route arguments. For example:, (*6)

  • /:controller/:action/:arg (all parameters are required)
  • /(foo|bar)-:arg/gotcha (regex and partial parameter matching. Valid are /foo-123/gotcha, /bar-qwerty/gotcha, but not /qwerty/gotcha)
  • /:arg? (parameter arg can be ommited, but not /. Valid are /, /param, but not /sub/param)
  • /(:controller:(/:action:(/:arg)?)?)? (all parameters not required. Valid are /, /home, /home/index/val, but not /home/, /home/index/)

Parameter name must match regex [a-zA-Z_0-9]+.
By default :parameter match regex [^\/]+, but you can use your own filter:, (*7)

new Route('/:arg(\d+)?', // arg not required and can contains only numerics
    ['controller' => 'home', 'action' => 'index', 'arg' => null], // default values
)

If you need to use ( to match group, but not to filter parameter, use trailing : in parameter name: /:controller:(postfix1|postfix2) will match /homepostfix1 with controller = 'home'., (*8)

Built-in simple dependency injection container

You can use built-in dependency injection container to split app code into services (which will be loaded via autoload) and simply use it in controller's actions:, (*9)

class ControllerHome {
    public function index($arg, Request $request, DatabaseService $db){
        // ...
    }
}

Services constructors can use dependency injection too and require another services via same syntax., (*10)

Class SampleContainer impletents Psr\Container\ContainerInterface., (*11)

use Iassasin\Easyroute\Router;

$router = new Router();
/** @var SimpleContainer $container */
$container = $router->getContainer(); // get default container

// Instantiate and add services by hand
$container->setService(Database::class, new Database('login', 'password'));
// Disable automatic instantiation for services
$container->setAutowireEnabled(false);

Also you can use another dependency injection container:, (*12)

use Iassasin\Easyroute\Router;
use Iassasin\Easyroute\Http\Request;

$router = new Router();
$request = Request::createFromGlobals();

// some implementation of ContainerInterface
$container = new MyContainer();
// Router don't know how to register Request class in your container implementation
// You should to do it by self if you want to use Request class in controllers
// See next section for details of Request class
$container->register(Request::class, $request);

$router->setContainer($container);

Request class

Using dependency injection container you have access to Request service that provides access to request parameters., (*13)

Request has fields listed below:, (*14)

  • query - $_GET array
  • request - $_POST array
  • attributes - assoc array with any data, which you can set at Request instance creation
  • cookies - $_COOKIE array
  • files - $_FILES array
  • server - $_SERVER array

Each field is instance of Parameters class and has methods:, (*15)

  • get(string $name) - get parameter by it's name
  • has(string $name) - does parameter with $name exists
  • all() - get all parameters in array

Request provide some useful methods:, (*16)

  • getContent() - get whole http post content as string
  • getClientIP() - returns $this->server->get('REMOTE_ADDR')
  • getScriptName() - returns $this->server->get('SCRIPT_NAME')
  • getScheme() - returns $this->server->get('REQUEST_SCHEME')
  • getHost() - returns $this->server->get('SERVER_NAME')
  • getUri() - returns $this->server->get('REQUEST_URI')
  • getMethod() - returns $this->server->get('REQUEST_METHOD')
  • getProtocol() - returns $this->server->get('SERVER_PROTOCOL')

Response class

Response class used to return data to client. Return Response instances from controller's actions instead of manual data send using echo or etc., (*17)

Built-in response classes

There is 3 built-in response classes:, (*18)

  • Response - base class for all responses, has methods:
    • __construct(string $content, int $statusCode = 200, array $headers = [])
    • getStatusCode(), setStatusCode(int $code) - get/set http status code
    • getContent(), setContent(string $content) - get/set http response content
    • getHeaders(), setHeaders(array $headers) - get/set http headers
    • setHeader(string $name, string $value) - set single header
    • send() - send response to client, called from handlers
  • Response404 - extends Request for default http 404 error with:
    • __construct(string $url, array $headers = [])
    • getUrl() - get URL caused 404 error
  • Response500 - extends Request for default http 500 error. Generated if any exception thrown during route processing.
    • __construct(\Throwable $exception = null, array $headers = [])
    • getException() - get exception thrown during route processing
  • ResponseJson - extends Request for sending json responses, also set correct http Content-Type header.
    • __construct(object|array $data, int $statusCode = 200, array $headers = [])
    • getData(), setData(object|array $data) - set source data to send to client
    • Note that setContent can't be used and throws LogicException

Custom handlers for response classes

Set custom handlers for Response classes:, (*19)

use Iassasin\Easyroute\Http\Responses\Response404;

$router->setResponseHandler(Response404::class, function(Response404 $resp){
    $resp->setContent('<html><body>

Custom 404 Not Found

The requested url "<i>'.htmlspecialchars($resp->getUrl()).'</i>" not found!'); $resp->send(); return true; // do not call other handlers });

And custom handlers for any http status code:, (*20)

use Iassasin\Easyroute\Http\Response;

$router->setStatusHandler(302, function(Response $resp){
    $resp->setContent('You have redirected');
    $resp->send();
    return true; // do not call other handlers
});

Note 1: you can use both handlers set, but response handlers will be called first (and can stop calling status handlers)., (*21)

Note 2: you can set handler for parent response class to match all childs, child handlers will be always called first: from most child to first parent. So, you can match all responses setting handler for Response::class., (*22)

Subdirectories for controllers

Separate zones with subdirectories:, (*23)

(new Route('/admin/:controller/:action?', ['action' => 'index']))
    ->setControllersSubpath('zones/admin')
    // '/admin/home/index' will match 'controllers/zones/admin/home.php'
    // and class 'ControllerHome'

Filtering access

Use RouteFilter to prevent access to some routes:, (*24)

use Iassasin\Easyroute\RouteFilter;

class RouteFilterAdmin extends RouteFilter {
    public function preRoute($path, $controller, $action, $args){
        if (!isCurrentUserAdmin()){
            (new Response('Access denied!', 403))->send();
            return Router::COMPLETED; // Do not call controller's action
        }

        return Router::CONTINUE; // Call controller's action
    }
}
//...
(new Route('/admin/:controller/:action?', ['action' => 'index']))
    ->setFilter(new RouteFilterAdmin())

Custom controller class name prefix

Set custom controller class name prefix (default - Controller):, (*25)

$router->setControllerClassPrefix('TheController');

The Versions

14/02 2018

dev-master

9999999-dev https://github.com/iassasin/easyroute

Very lightweight and simple router for PHP

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar iassasin

mvc route controller router

14/02 2018

v0.9.0

0.9.0.0 https://github.com/iassasin/easyroute

Very lightweight and simple router for PHP

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar iassasin

mvc route controller router

29/01 2018

v0.7.0

0.7.0.0 https://github.com/iassasin/easyroute

Very lightweight and simple router for PHP

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar iassasin

mvc route controller router

28/01 2018

v0.5.0

0.5.0.0 https://github.com/iassasin/easyroute

Very lightweight and simple router for PHP

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar iassasin

mvc route controller router

27/01 2018

v0.4.0

0.4.0.0 https://github.com/iassasin/easyroute

Very lightweight and simple router for PHP

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar iassasin

mvc route controller router

10/09 2017

v0.3.3

0.3.3.0 https://github.com/iassasin/easyroute

Very lightweight and simple router for PHP

  Sources   Download

MIT

The Requires

  • php >=5.6

 

The Development Requires

by Avatar iassasin

mvc route controller router

07/09 2017

v0.3.2

0.3.2.0 https://github.com/iassasin/easyroute

Very lightweight and simple router for PHP

  Sources   Download

MIT

The Requires

  • php >=5.6

 

The Development Requires

by Avatar iassasin

mvc route controller router

06/09 2017

v0.3.1

0.3.1.0 https://github.com/iassasin/easyroute

Very lightweight and simple router for PHP

  Sources   Download

MIT

The Requires

  • php >=5.6

 

The Development Requires

by Avatar iassasin

mvc route controller router

06/09 2017

v0.3.0

0.3.0.0 https://github.com/iassasin/easyroute

Very lightweight and simple router for PHP

  Sources   Download

MIT

The Requires

  • php >=5.6

 

The Development Requires

by Avatar iassasin

mvc route controller router

19/08 2017

v0.2.1

0.2.1.0 https://github.com/iassasin/easyroute

Very lightweight and simple router for PHP

  Sources   Download

MIT

The Requires

  • php >=5.6

 

The Development Requires

by Avatar iassasin

mvc route controller router

19/08 2017

v0.2.0

0.2.0.0 https://github.com/iassasin/easyroute

Very lightweight and simple router for PHP

  Sources   Download

MIT

The Requires

  • php >=5.6

 

The Development Requires

by Avatar iassasin

mvc route controller router