diff --git a/.htaccess b/.htaccess
index a491805..8ef0a37 100644
--- a/.htaccess
+++ b/.htaccess
@@ -4,6 +4,7 @@ DirectoryIndex index.php
RewriteEngine on
# set your rewrite base
+# Edit this in your init method too if you script lives in a subfolder
RewriteBase /
# Deliver the folder or file directly if it exists on the server
diff --git a/README.md b/README.md
index 9510eb2..e390692 100644
--- a/README.md
+++ b/README.md
@@ -1,27 +1,33 @@
# 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.
+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.
-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 first argument takes the path segment. You can also use RegExp in there to parse out variables.
+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){
- //Do something
+include('Route.php');
+
+Route::add('/user/([0-9]*)/edit',function($id){
echo 'Edit user with id '.$id.'
';
-});
+},'get');
+
+Route::run('/');
```
-## Testing
-* Clone or download this repo
-* Cd into the repo folder and run:
-* ```php -S 0.0.0.0:8080```
-* Than open your Webbrowser and navigate to http://localhost:8080
+You will find a more complex example with a build in navigation in the index.php file.
+
+## Use a different basepath
+If your script lives in a subfolder e.g. /api/v1 set this basepath in your run method:
+```Route::run('/api/v1');```
+Do not forget to edit the basepath in .htaccess if you are on apache
## 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
diff --git a/Route.php b/Route.php
index 08ec516..657c53c 100644
--- a/Route.php
+++ b/Route.php
@@ -3,84 +3,99 @@
class Route{
private static $routes = Array();
- private static $routes404 = Array();
- private static $path;
- private static $basepath = '/';
+ private static $pathNotFound = null;
+ private static $methodNotAllowed = null;
+
+ 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 = '/'){
-
- self::$basepath = $basepath;
-
+ public static function run($basepath = '/'){
+
+ // Parse current url
$parsed_url = parse_url($_SERVER['REQUEST_URI']);//Parse Uri
if(isset($parsed_url['path'])){
- self::$path = $parsed_url['path'];
+ $path = $parsed_url['path'];
}else{
- self::$path = '/';
+ $path = '/';
}
- }
-
- public static function add($expression,$function){
-
- array_push(self::$routes,Array(
- 'expression'=>$expression,
- 'function'=>$function
- ));
-
- }
-
- public static function add404($function){
-
- array_push(self::$routes404,$function);
-
- }
-
- public static function run(){
-
- $route_found = false;
+ // Get current request method
+ $method = $_SERVER['REQUEST_METHOD'];
+
+ $path_match_found = false;
+
+ $route_match_found = false;
foreach(self::$routes as $route){
-
+
+ // If the method matches check the path
+
// Add basepath to matching string
- if(self::$basepath!=''&&self::$basepath!='/'){
- $route['expression'] = '('.self::$basepath.')'.$route['expression'];
- }
-
- // Add 'find string start' automatically
- $route['expression'] = '^'.$route['expression'];
+ if($basepath!=''&&$basepath!='/'){
+ $route['expression'] = '('.$basepath.')'.$route['expression'];
+ }
+
+ // Add 'find string start' automatically
+ $route['expression'] = '^'.$route['expression'];
- // Add 'find string end' automatically
- $route['expression'] = $route['expression'].'$';
+ // Add 'find string end' automatically
+ $route['expression'] = $route['expression'].'$';
// echo $route['expression'].'
';
- // Check match
- if(preg_match('#'.$route['expression'].'#',self::$path,$matches)){
-
- array_shift($matches);// Always remove first element. This contains the whole string
-
- if(self::$basepath!=''&&self::$basepath!='/'){
-
- array_shift($matches);// Remove Basepath
-
- }
-
- call_user_func_array($route['function'], $matches);
-
- $route_found = true;
-
+ // Check path match
+ if(preg_match('#'.$route['expression'].'#',$path,$matches)){
+
+ $path_match_found = true;
+
+ // Check method match
+ if(strtolower($method) == strtolower($route['method'])){
+
+ array_shift($matches);// Always remove first element. This contains the whole string
+
+ if($basepath!=''&&$basepath!='/'){
+ array_shift($matches);// Remove basepath
+ }
+
+ 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){
-
- call_user_func_array($route404, Array(self::$path));
-
- }
+ // But a matching path exists
+ if($path_match_found){
+ 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));
+ }
+ }
}
diff --git a/index.php b/index.php
index f10afc2..4fc1836 100644
--- a/index.php
+++ b/index.php
@@ -1,76 +1,4 @@
-';
-});
-
-// 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 :-)
';
-});
-
-// 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.'
';
-});
-
-// Add a 404 not found route
-Route::add404(function($url){
-
- // Send 404 Header
- header("HTTP/1.0 404 Not Found");
- echo '404 :-(
';
- echo $url.' not found!';
-
-});
-
-// Check if any of the defined routes will match and execute them
-Route::run();
-
-?>
-
-