Complete refactoring
This commit is contained in:
parent
47ce76fbb7
commit
2b76b40d82
|
@ -4,6 +4,7 @@ DirectoryIndex index.php
|
||||||
RewriteEngine on
|
RewriteEngine on
|
||||||
|
|
||||||
# set your rewrite base
|
# set your rewrite base
|
||||||
|
# Edit this in your init method too if you script lives in a subfolder
|
||||||
RewriteBase /
|
RewriteBase /
|
||||||
|
|
||||||
# Deliver the folder or file directly if it exists on the server
|
# Deliver the folder or file directly if it exists on the server
|
||||||
|
|
34
README.md
34
README.md
|
@ -1,27 +1,33 @@
|
||||||
# Simple PHP Router
|
# Simple PHP Router
|
||||||
|
|
||||||
Hey! This is a simple class that can handel the whole url routing for your project.
|
Hey! This is a simple and small php router that can handel the whole url routing for your project.
|
||||||
|
|
||||||
It utilizes RegExp and PHPs anonymous functions to create a lightweight and fast routing system.
|
It utilizes RegExp and PHPs anonymous functions to create a lightweight and fast routing system.
|
||||||
|
The router supports dynamic path parameters, special 404 and 405 routes as well as verification of request methods like get, post, put, delete etc...
|
||||||
|
The codebase is very small and very easy to understand. So you can use it as boilerplate for a more complex router.
|
||||||
|
|
||||||
Take a look in the index.php file. As you can see the ```Route::add()``` method is used to add new routes to your project.
|
Take a look in the index.php file. As you can see the ```Route::add()``` method is used to add new routes to your project.
|
||||||
The first argument takes the path segment. You can also use RegExp in there to parse out variables.
|
The first argument takes the path segment. You can also use RegExp in there to parse out variables.
|
||||||
All matches will be pushed to the handler method. The handler is the second argument of the add function.
|
The second argument will match the request method. The default method is 'get'.
|
||||||
|
All matching variables will be pushed to the handler method.
|
||||||
|
|
||||||
Example:
|
## Simple example:
|
||||||
```
|
```
|
||||||
Route::add('/user/(.*)/edit',function($id){
|
include('Route.php');
|
||||||
//Do something
|
|
||||||
|
Route::add('/user/([0-9]*)/edit',function($id){
|
||||||
echo 'Edit user with id '.$id.'<br/>';
|
echo 'Edit user with id '.$id.'<br/>';
|
||||||
});
|
},'get');
|
||||||
|
|
||||||
|
Route::run('/');
|
||||||
```
|
```
|
||||||
|
|
||||||
## Testing
|
You will find a more complex example with a build in navigation in the index.php file.
|
||||||
* Clone or download this repo
|
|
||||||
* Cd into the repo folder and run:
|
## Use a different basepath
|
||||||
* ```php -S 0.0.0.0:8080```
|
If your script lives in a subfolder e.g. /api/v1 set this basepath in your run method:
|
||||||
* Than open your Webbrowser and navigate to http://localhost:8080
|
```Route::run('/api/v1');```
|
||||||
|
Do not forget to edit the basepath in .htaccess if you are on apache
|
||||||
|
|
||||||
## Something does not work?
|
## Something does not work?
|
||||||
* Dont forget to set the basepath in your index.php and .htaccess file.
|
* Dont forget to set the correct basepath as argument in your run method and in your .htaccess file.
|
||||||
* Enable mod_rewrite in your apache settings
|
* Enable mod_rewrite in your apache settings
|
||||||
|
|
135
Route.php
135
Route.php
|
@ -3,84 +3,99 @@
|
||||||
class Route{
|
class Route{
|
||||||
|
|
||||||
private static $routes = Array();
|
private static $routes = Array();
|
||||||
private static $routes404 = Array();
|
private static $pathNotFound = null;
|
||||||
private static $path;
|
private static $methodNotAllowed = null;
|
||||||
private static $basepath = '/';
|
|
||||||
|
public static function add($expression, $function, $method = 'get'){
|
||||||
|
array_push(self::$routes,Array(
|
||||||
|
'expression' => $expression,
|
||||||
|
'function' => $function,
|
||||||
|
'method' => $method
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function pathNotFound($function){
|
||||||
|
self::$pathNotFound = $function;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function methodNotAllowed($function){
|
||||||
|
self::$methodNotAllowed = $function;
|
||||||
|
}
|
||||||
|
|
||||||
public static function init($basepath = '/'){
|
public static function run($basepath = '/'){
|
||||||
|
|
||||||
self::$basepath = $basepath;
|
// Parse current url
|
||||||
|
|
||||||
$parsed_url = parse_url($_SERVER['REQUEST_URI']);//Parse Uri
|
$parsed_url = parse_url($_SERVER['REQUEST_URI']);//Parse Uri
|
||||||
|
|
||||||
if(isset($parsed_url['path'])){
|
if(isset($parsed_url['path'])){
|
||||||
self::$path = $parsed_url['path'];
|
$path = $parsed_url['path'];
|
||||||
}else{
|
}else{
|
||||||
self::$path = '/';
|
$path = '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
// Get current request method
|
||||||
|
$method = $_SERVER['REQUEST_METHOD'];
|
||||||
public static function add($expression,$function){
|
|
||||||
|
$path_match_found = false;
|
||||||
array_push(self::$routes,Array(
|
|
||||||
'expression'=>$expression,
|
$route_match_found = false;
|
||||||
'function'=>$function
|
|
||||||
));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function add404($function){
|
|
||||||
|
|
||||||
array_push(self::$routes404,$function);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function run(){
|
|
||||||
|
|
||||||
$route_found = false;
|
|
||||||
|
|
||||||
foreach(self::$routes as $route){
|
foreach(self::$routes as $route){
|
||||||
|
|
||||||
|
// If the method matches check the path
|
||||||
|
|
||||||
// Add basepath to matching string
|
// Add basepath to matching string
|
||||||
if(self::$basepath!=''&&self::$basepath!='/'){
|
if($basepath!=''&&$basepath!='/'){
|
||||||
$route['expression'] = '('.self::$basepath.')'.$route['expression'];
|
$route['expression'] = '('.$basepath.')'.$route['expression'];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add 'find string start' automatically
|
// Add 'find string start' automatically
|
||||||
$route['expression'] = '^'.$route['expression'];
|
$route['expression'] = '^'.$route['expression'];
|
||||||
|
|
||||||
// Add 'find string end' automatically
|
// Add 'find string end' automatically
|
||||||
$route['expression'] = $route['expression'].'$';
|
$route['expression'] = $route['expression'].'$';
|
||||||
|
|
||||||
// echo $route['expression'].'<br/>';
|
// echo $route['expression'].'<br/>';
|
||||||
|
|
||||||
// Check match
|
// Check path match
|
||||||
if(preg_match('#'.$route['expression'].'#',self::$path,$matches)){
|
if(preg_match('#'.$route['expression'].'#',$path,$matches)){
|
||||||
|
|
||||||
array_shift($matches);// Always remove first element. This contains the whole string
|
$path_match_found = true;
|
||||||
|
|
||||||
if(self::$basepath!=''&&self::$basepath!='/'){
|
// Check method match
|
||||||
|
if(strtolower($method) == strtolower($route['method'])){
|
||||||
array_shift($matches);// Remove Basepath
|
|
||||||
|
array_shift($matches);// Always remove first element. This contains the whole string
|
||||||
}
|
|
||||||
|
if($basepath!=''&&$basepath!='/'){
|
||||||
call_user_func_array($route['function'], $matches);
|
array_shift($matches);// Remove basepath
|
||||||
|
}
|
||||||
$route_found = true;
|
|
||||||
|
call_user_func_array($route['function'], $matches);
|
||||||
|
|
||||||
|
$route_match_found = true;
|
||||||
|
|
||||||
|
// Do not check other routes
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$route_found){
|
// No matching route was found
|
||||||
|
if(!$route_match_found){
|
||||||
|
|
||||||
foreach(self::$routes404 as $route404){
|
// But a matching path exists
|
||||||
|
if($path_match_found){
|
||||||
call_user_func_array($route404, Array(self::$path));
|
header("HTTP/1.0 405 Method Not Allowed");
|
||||||
|
if(self::$methodNotAllowed){
|
||||||
}
|
call_user_func_array(self::$methodNotAllowed, Array($path,$method));
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
header("HTTP/1.0 404 Not Found");
|
||||||
|
if(self::$pathNotFound){
|
||||||
|
call_user_func_array(self::$pathNotFound, Array($path));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
159
index.php
159
index.php
|
@ -1,76 +1,4 @@
|
||||||
<?PHP
|
|
||||||
|
|
||||||
// Include needed files
|
|
||||||
include('Route.php');
|
|
||||||
|
|
||||||
// Init routing and configure basepath
|
|
||||||
// If your script lives in the web root folder use a / , leave it empty or do not define this config
|
|
||||||
Route::init('/');
|
|
||||||
|
|
||||||
// If your script lives in a subfolder you can use the following example
|
|
||||||
// Route::init('/api/v1');
|
|
||||||
|
|
||||||
// Base route (startpage)
|
|
||||||
Route::add('/',function(){
|
|
||||||
// Do something
|
|
||||||
echo 'Welcome :-)';
|
|
||||||
});
|
|
||||||
|
|
||||||
// Another base route example
|
|
||||||
Route::add('/index.php',function(){
|
|
||||||
// Do something
|
|
||||||
echo 'You are not realy on index.php ;-)';
|
|
||||||
});
|
|
||||||
|
|
||||||
// Simple route
|
|
||||||
Route::add('/test.html',function(){
|
|
||||||
// Do something
|
|
||||||
echo 'Hello from test.html';
|
|
||||||
});
|
|
||||||
|
|
||||||
// Complex route with parameter
|
|
||||||
// Be aware that (.*) will match / too. For example: /user/foo/bar/edit
|
|
||||||
// Also users could inject mysql-code or other unchecked data if you use (.*)
|
|
||||||
// You should better use a saver expression like /user/([0-9]*)/edit or /user/([A-Za-z]*)/edit
|
|
||||||
Route::add('/user/(.*)/edit',function($id){
|
|
||||||
// Do something
|
|
||||||
echo 'Edit user with id '.$id.'<br/>';
|
|
||||||
});
|
|
||||||
|
|
||||||
// Accept only numbers as the second parameter. Other characters will result in a 404
|
|
||||||
Route::add('/foo/([0-9]*)/bar',function($var1){
|
|
||||||
// Do something
|
|
||||||
echo $var1.' is a great number!';
|
|
||||||
});
|
|
||||||
|
|
||||||
// Long route example
|
|
||||||
Route::add('/foo/bar/foo/bar',function(){
|
|
||||||
// Do something
|
|
||||||
echo 'hehe :-)<br/>';
|
|
||||||
});
|
|
||||||
|
|
||||||
// Crazy route with parameters (Will be triggered on the route pattern above too because it matches too)
|
|
||||||
Route::add('/(.*)/(.*)/(.*)/(.*)',function($var1,$var2,$var3,$var4){
|
|
||||||
// Do something
|
|
||||||
echo 'You have entered: '.$var1.' / '.$var2.' / '.$var3.' / '.$var4.'<br/>';
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add a 404 not found route
|
|
||||||
Route::add404(function($url){
|
|
||||||
|
|
||||||
// Send 404 Header
|
|
||||||
header("HTTP/1.0 404 Not Found");
|
|
||||||
echo '404 :-(<br/>';
|
|
||||||
echo $url.' not found!';
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// Check if any of the defined routes will match and execute them
|
|
||||||
Route::run();
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<hr/>
|
|
||||||
Navigation:
|
Navigation:
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="/">home</a></li>
|
<li><a href="/">home</a></li>
|
||||||
|
@ -78,5 +6,90 @@ Navigation:
|
||||||
<li><a href="/user/3/edit">edit user 3</a></li>
|
<li><a href="/user/3/edit">edit user 3</a></li>
|
||||||
<li><a href="/foo/5/bar">foo 5 bar</a></li>
|
<li><a href="/foo/5/bar">foo 5 bar</a></li>
|
||||||
<li><a href="/foo/bar/foo/bar">long route example</a></li>
|
<li><a href="/foo/bar/foo/bar">long route example</a></li>
|
||||||
<li><a href="/test.html">test.html</a> (May not work with PHPs built in webserver. Try apache webserver.)</li>
|
<li><a href="/contact-form">contact form</a></li>
|
||||||
|
<li><a href="/test.html">test.html</a></li>
|
||||||
|
<li><a href="/this-route-is-not-defined">404 Test</a></li>
|
||||||
|
<li><a href="/this-route-is-defined">405 Test</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<?PHP
|
||||||
|
|
||||||
|
// Include router class
|
||||||
|
include('Route.php');
|
||||||
|
|
||||||
|
// Add base route (startpage)
|
||||||
|
Route::add('/',function(){
|
||||||
|
echo 'Welcome :-)';
|
||||||
|
});
|
||||||
|
|
||||||
|
// Another base route example
|
||||||
|
Route::add('/index.php',function(){
|
||||||
|
echo 'You are not realy on index.php ;-)';
|
||||||
|
});
|
||||||
|
|
||||||
|
// Simple test route that simulates static html file
|
||||||
|
Route::add('/test.html',function(){
|
||||||
|
echo 'Hello from test.html';
|
||||||
|
});
|
||||||
|
|
||||||
|
// Post route example
|
||||||
|
Route::add('/contact-form',function(){
|
||||||
|
echo '<form method="post"><input type="text" name="test" /><input type="submit" value="send" /></form>';
|
||||||
|
},'get');
|
||||||
|
|
||||||
|
// Post route example
|
||||||
|
Route::add('/contact-form',function(){
|
||||||
|
echo 'Hey! The form has been sent:<br/>';
|
||||||
|
print_r($_POST);
|
||||||
|
},'post');
|
||||||
|
|
||||||
|
// Route with regexp parameter
|
||||||
|
// Be aware that (.*) will match / (slash) too. For example: /user/foo/bar/edit
|
||||||
|
// Also users could inject mysql-code or other untrusted data if you use (.*)
|
||||||
|
// You should better use a saver expression like /user/([0-9]*)/edit or /user/([A-Za-z]*)/edit
|
||||||
|
Route::add('/user/(.*)/edit',function($id){
|
||||||
|
echo 'Edit user with id '.$id.'<br/>';
|
||||||
|
});
|
||||||
|
|
||||||
|
// Accept only numbers as parameter. Other characters will result in a 404 error
|
||||||
|
Route::add('/foo/([0-9]*)/bar',function($var1){
|
||||||
|
echo $var1.' is a great number!';
|
||||||
|
});
|
||||||
|
|
||||||
|
// Crazy route with parameters
|
||||||
|
Route::add('/(.*)/(.*)/(.*)/(.*)',function($var1,$var2,$var3,$var4){
|
||||||
|
echo 'This is the first match: '.$var1.' / '.$var2.' / '.$var3.' / '.$var4.'<br/>';
|
||||||
|
});
|
||||||
|
|
||||||
|
// Long route example
|
||||||
|
// This route gets never triggered because the route before matches too
|
||||||
|
Route::add('/foo/bar/foo/bar',function(){
|
||||||
|
echo 'This is the second match <br/>';
|
||||||
|
});
|
||||||
|
|
||||||
|
// 405 test
|
||||||
|
Route::add('/this-route-is-defined',function(){
|
||||||
|
echo 'You need to patch this route to see this content';
|
||||||
|
},'patch');
|
||||||
|
|
||||||
|
// Add a 404 not found route
|
||||||
|
Route::pathNotFound(function($path){
|
||||||
|
echo 'Error 404 :-(<br/>';
|
||||||
|
echo 'The requested path "'.$path.'" was not found!';
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add a 405 method not allowed route
|
||||||
|
Route::methodNotAllowed(function($path, $method){
|
||||||
|
echo 'Error 405 :-(<br/>';
|
||||||
|
echo 'The requested path "'.$path.'" exists. But the request method "'.$method.'" is not allowed on this path!';
|
||||||
|
});
|
||||||
|
|
||||||
|
// Run the Router with the given Basepath
|
||||||
|
// If your script lives in the web root folder use a / or leave it empty
|
||||||
|
Route::run('/');
|
||||||
|
|
||||||
|
// If your script lives in a subfolder you can use the following example
|
||||||
|
// Do not forget to edit the basepath in .htaccess if you are on apache
|
||||||
|
// Route::run('/api/v1');
|
||||||
|
|
||||||
|
?>
|
Loading…
Reference in New Issue
Block a user