A REST / SHELL / API Requests Routing System: it provides "a centralized entry point for handling requests".
Stop making tons of .php files to handle each ajax.
Stop making static and separated .php files to handle each cron.
- Front Control Pattern implementation with no pain or hassling
- Centralized entry point to handle all app requests and more
- Strict parameters count and name validation
- Self defined authentication and authorization methods
- PHP 5.4.9 or higher
- 5 minutes of your life
Suppose to have the following within your project:
class Animal
{
public static function eat($hotdogs, $mayo = true, $ketchup = false)
{ return "yum!"; }
}
- You can fire within a shell:
$> php Router.php 'Animal/eat?hotdogs=2&mayo=false'
- You can fire within a browser
www.mydomain.com/r/Animal/eat?hotdogs=2&mayo=false
The output is the pretty printed JSON encoded value returned by the funcion.
{
"data": "yum!"
}
If you didn't already know, you can pass array and hashes (objects) using this syntax:
class Animal
{
public static function eat($hotdogs, $mayo = true, $ketchup = false)
{ return get_defined_vars(); }
}
$> php Router.php 'Animal/eat?hotdogs[first]=big&hotdogs[second]=very_big&mayo[]=first_array_element&mayo[]=second_array_element'
$> curl www.mydomain.com/r/Animal/eat?hotdogs[first]=big&hotdogs[second]=very_big&mayo[]=first_array_element&mayo[]=second_array_element
Output:
{
"data": {
"hotdogs": {
"first": "big",
"second": "very_big"
},
"mayo": [
"first_array_element",
"second_array_element"
],
"ketchup": false
}
}
- Put the following in your .htaccess, assuming you want the request to the r/ path to be mapped to the Router:
RewriteCond %{REQUEST_URI} ^\/r\/([\w\d]+)?\/([\w\d]+)$
RewriteRule r\/([\w\d]+)?\/([\w\d]+) php/Router.php?called_class=$1&called_method=$2 [L,QSA]
- Require a config or directly define the autoloader at the top of your Router.php
The Router auto checks the followings:
- The method requested exists
- The passed parameters count is equal or greater then the method mandatory parameters count
- The passed parameters count is not greater then the method parameters count
- The passed parameters names match the method parameters names
If one check fails the Router will return a built-in error.
#### Security The Router defaults to the Allow / Deny policy: if you do not provide the auth* methods then no access will be provided your app. If you just wanna test it, then you can simply set the config var $allow_policy to true. Then you (and anyone else..) will gain access to anything within your classes (even PHP built-in classes off course!):Router::$allow_policy = true;
Otherwise follows these guidelines: in the following example I'll be using a ranking system, but you can use whichever logic you wish!
Define an auth obj for each method within your class:
class Animal
{
static $auth = [
"eat" => 2, # just using an int standing for the ranking level needed
"drink" => 3
];
public static function eat($hotdogs, $ketchup = false)
{ return "yum!"; }
public static function drink($coke, $diet = true)
{ return "slurp!"; }
}
Define the authentication method that will be used to compare the method auth and the user auth:
Router::$authentication_method = function(){
return User::getMyRank();
};
Define the authorization method the Router will use to allow class methods access. The authorization method takes two parameters:
- The requesting user auth returned by the Authentication method
- The requested method auth obj defined within the class
The logic is up to you: just return a boolean to indicate whether the user has access to the requested method.
Router::$authorization_method = function($my_auth, $method_auth){
# is my ranking higher or equal to the rank needed for the method?
if($my_auth >= $method_auth)
return true;
else
return false;
};