noordawod/micro-router

A modular, low-memory and fast PHP router with a pluggable soul.

dev-master 2015-01-11 19:26 UTC

This package is not auto-updated.

Last update: 2019-09-09 02:38:43 UTC


README

So, do we need yet another router to do REST and all other crazy things?

If you consider the following, you might be convinced to try it out:

  • One namespace to rule them all (no fiddling with global scope)

  • Insane low memory footprint + only needed classes are loaded

  • Engineered from the first line of code to be highly modular, configurable and developer-friendly

  • Except for the \Fine47\MicroRouter class (which keeps track of few basic utilities,) all else is interface-based and switchable

  • Very abstract take on client-server communication (client and server components are modular, too)

  • Filters allow the developer to intercept requests to perform pre- and post-handling logic

  • Exceptions are thrown when errors occur (you don't have to test for NULL, FALSE, etc.)

  • The library is pre-equipped with a class for handling HTTP requests (using JSON)

  • The library is pre-equipped with a class for file-based routing (no fiddling with yaml, XML, JSON or PHP config files to define routes; just create a new file that implements Action interface)

  • The best of all: If you don't like a pre-equipped implementation, switch it out and create your own -- it's that easy as all classes implement simple interfaces

  • The library comes with implementations for these developer-friendly utilities:

    • Flash support using cookies
    • Session support using cookies only (no backend on the server is needed, so it's truly stateless)
    • Encryptor class that facilitates encrypting and decrypting numeric numbers and binary data (great for creating tokens)
    • Hasher class for one-way hashing, provides support for SIP algorithm if the PHP module is properly installed
    • Logger class for both file-based and PHP error-log-based logging
    • HTTP Request handling with JSON as the transport protocol

Ok, interesting; show me the code!

Sure thing, amigo. The following is a "Hello, world"-style code to demonstrate:

<?php

namespace MyApp;

use Fine47\MicroRouter\Encryptors;
use Fine47\MicroRouter\Routers;
use Fine47\MicroRouter\Requests;
use Fine47\MicroRouter\Import;

require_once 'path/to/micro-router/src/micro-router.php';

Import::impl([
  Import::TYPE_ROUTER => 'files',
  Import::TYPE_REQUEST => 'http',
  Import::TYPE_ENCRYPTOR => 'rijndael'
]);

// Create a new MicroRouter handler.
$engine = new \Fine47\MicroRouter(\Fine47\MicroRouter::DEVELOPMENT);

// Configure the engine to use a files-based router.
$engine->setRouter(new Routers\Files(['../routes']));

// Configure the engine to use RIJNDAEL encryptor.
$engine->setEncryptor(new Encryptors\Rijndael(
  \MCRYPT_RIJNDAEL_128,
  'CHANGE-ME',
  '0123456789fedcba'
));

// Serve the request using engine.
$engine->execute(new Requests\Http('/'));

Hey amigo, that's a lot of code

You might think so indeed just by looking at the above code, but take my word for it: other libraries do exactly the same, but behind the scenes. So, in the case of MicroRouter, you actually see the beauty of the code as well :)

You either like it or don't. Up to you.

Visual decision making of the router

Install easily with composer

The recommended way of requiring a library is using composer require command. This leads composer to picking the proper version constraint (i.e ~1.2), updating composer.json and running install, all in one command.

$ composer require noordawod/micro-router

If you need a specific version or to tail the development version, just change the command to read:

$ composer require noordawod/micro-router:dev-master@dev

Bottom line: Do not edit composer.json directly, let composer do that (a tip generously provided by rdohms, thanks mate.)

Directory structure

After downloading the library (as a ZIP file, or by cloning the repo) and extracting the files, the directory structure will be like so:

example/

    logs/
    public/
    routes/

src/

    exceptions/

    impl/

        encryptors/
        engines/
        filters/
        hashers/
        loggers/
        requests/

    interfaces/

    util/

And here's an explanation for most of these directories:

example/

Top-level directory holding an example app to route requests using file-based router.

example/public/

Publicly-accessible document root of the website (this is the value for DOCUMENT_ROOT in your web server of choice.)

example/routes/

Routing handlers are here. Note that the default router implementation requires that this directory is outside the publicly-accessible document root of the website (which is correct in this case).

Routing handlers are just PHP scripts kept in a directory structure that resembles the request's URI. So for example, if you want to handle a call to /hello/world, then create a directory structure like so:

example/routes/hello/world (this structure should be there already)

Then, create a file called get.php (or post.php, head.php, etc.) to handle different request methods (GET, POST, HEAD, etc.)

src/

Top-level directory which hosts all the library's files. There are two files inside this directory:

config.php:

App configuration with sane values used for the HttpAuto engine. Developers can, of course, change the defaults before serving the request. Note: If you load this file, it will load the next one so you don't have to load it yourself.

micro-router.php:

The library's main class file (this is home of the \Fine47\MicroRouter class).

src/exceptions/

Just like the name implies, this directory hosts all classes which provide exceptions support. To assist developers in finding errors in their code, we added a Magic parameter to exceptions (a simple hexadecimal integer) in order to allow developers to find errors by simply searching for this value.

src/impl/

Top-level directory hosting default implementations of all interfaces. Because of the way MicroRouter is engineered, if you don't like a particular implementation, you don't have to use it -- just write your own and use it instead.

src/interfaces/

All interfaces of the library are here. By investigating the various interfaces, you could get an understanding on how the library is constructed. It's also safe to assume that any interface that you see here can be implemented by you in a totally different manner than the default one.

src/util/

Generic utilities (implemented as static functions) needed for the library's operation, but could also be safely used in your app.