Unified the code style across the project, fixed grammar issues, added TODOs
This commit is contained in:
parent
9cc623d215
commit
8a198bc168
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -1,2 +1,6 @@
|
||||||
# vagrant files
|
# Vagrant files
|
||||||
.vagrant
|
.vagrant
|
||||||
|
|
||||||
|
# OS files
|
||||||
|
.DS_Store
|
||||||
|
._*
|
||||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2018-2019 SteamPixel and contributors
|
Copyright (c) 2018 - 2020 SteamPixel and contributors
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
26
README.md
26
README.md
|
@ -5,13 +5,13 @@ It utilizes RegExp and PHP's anonymous functions to create a lightweight and fas
|
||||||
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 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 a boilerplate for a more complex router.
|
The codebase is very small and very easy to understand. So you can use it as a boilerplate for a more complex router.
|
||||||
|
|
||||||
Take a look at the index.php file. As you can see the ```Route::add()``` method is used to add new routes to your project.
|
Take a look at 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 matching variables will be pushed to the handler method defined in the second argument.
|
All matching variables will be pushed to the handler method defined in the second argument.
|
||||||
The third argument will match the request method. The default method is 'get'.
|
The third argument will match the request method. The default method is 'get'.
|
||||||
|
|
||||||
## Simple example:
|
## Simple example:
|
||||||
```
|
```php
|
||||||
include 'Route.php';
|
include 'Route.php';
|
||||||
|
|
||||||
Route::add('/user/([0-9]*)/edit', function($id) {
|
Route::add('/user/([0-9]*)/edit', function($id) {
|
||||||
|
@ -26,36 +26,38 @@ You will find a more complex example with a build in navigation in the index.php
|
||||||
## Use a different basepath
|
## Use a different basepath
|
||||||
If your script lives in a subfolder (e.g. /api/v1) set this basepath in your run method:
|
If your script lives in a subfolder (e.g. /api/v1) set this basepath in your run method:
|
||||||
|
|
||||||
```Route::run('/api/v1');```
|
```php
|
||||||
|
Route::run('/api/v1');
|
||||||
|
```
|
||||||
|
|
||||||
Do not forget to edit the basepath in .htaccess too if you are on Apache2. In order to run the test files correctly inside a basepath you should also adjust the navigation links inside the index.php.
|
Do not forget to edit the basepath in .htaccess too if you are on Apache2. In order to run the test files correctly inside a basepath you should also adjust the navigation links inside the index.php.
|
||||||
|
|
||||||
## Enable case sensitive routes and trailing slashes
|
## Enable case sensitive routes and trailing slashes
|
||||||
The second and third parameters of ```Route::run('/', false, false);``` are both set to false by default.
|
The second and third parameters of `Route::run('/', false, false);` are both set to false by default.
|
||||||
You can enable case sensitive mode by setting the second parameter to true.
|
You can enable case sensitive mode by setting the second parameter to true.
|
||||||
By default the router will ignore trailing slashes. Set the third parameter to true to avoid this.
|
By default the router will ignore trailing slashes. Set the third parameter to true to avoid this.
|
||||||
|
|
||||||
## Something does not work?
|
## Something does not work?
|
||||||
* Dont forget to set the correct basepath as argument in your run method and in your .htaccess file.
|
* Don't forget to set the correct basepath as the first argument in your `run()` method and in your .htaccess file.
|
||||||
* Enable mod_rewrite in your Apache2 settings
|
* Enable mod_rewrite in your Apache2 settings, in case you're using Apache2: `a2enmod apache2`
|
||||||
|
|
||||||
## Test setup with Docker
|
## Test setup with Docker
|
||||||
I have created a little Docker test setup.
|
I have created a little Docker test setup.
|
||||||
|
|
||||||
1. Build the image: ```docker build -t simplephprouter docker/image```
|
1. Build the image: `docker build -t simplephprouter docker/image`
|
||||||
|
|
||||||
2. Spin up a container
|
2. Spin up a container
|
||||||
* On Linux / Mac or Windows Powershell use: ```docker run -d -p 80:80 -v $(pwd):/var/www/html --name simplephprouter simplephprouter```
|
* On Linux / Mac or Windows Powershell use: `docker run -d -p 80:80 -v $(pwd):/var/www/html --name simplephprouter simplephprouter`
|
||||||
* On Windows CMD use ```docker run -d -p 80:80 -v %cd%:/var/www/html --name simplephprouter simplephprouter```
|
* On Windows CMD use `docker run -d -p 80:80 -v %cd%:/var/www/html --name simplephprouter simplephprouter`
|
||||||
|
|
||||||
3. Open your browser and navigate to http://localhost
|
3. Open your browser and navigate to http://localhost
|
||||||
|
|
||||||
## Test setup with Vagrant (not longer maintained)
|
## Test setup with Vagrant (no longer maintained)
|
||||||
There is a little Vagrant test setup. Just run ```vagrant up``` to spin up an Apache2 web server on Ubuntu. Then navigate to http://router.local after adding the machine IP to your hosts file. This test setup is not longer maintained and will probably break in the future. Use the Docker test setup instead.
|
There is a little Vagrant test setup. Just run `vagrant up` to spin up an Apache2 web server on Ubuntu. Then navigate to http://router.local after adding the machine IP to your hosts file. This test setup is no longer maintained and will probably break in the future. Use the Docker test setup instead.
|
||||||
|
|
||||||
## Themes, layouts, pages and components
|
## Themes, layouts, pages and components
|
||||||
If you are interested in some basic concepts on how to build a simple PHP page using this router including themes, layouts, pages and components checkout this repo: https://github.com/steampixel/simplePHPPages
|
If you are interested in some basic concepts on how to build a simple PHP page using this router including themes, layouts, pages and components checkout this repo: https://github.com/steampixel/simplePHPPages
|
||||||
This project will give you some ideas and basics on how to get started with no dependencies.
|
This project will give you some ideas and basics on how to get started without any dependencies.
|
||||||
|
|
||||||
## Todo
|
## Todo
|
||||||
* Create demo configuration for nginx
|
* Create demo configuration for nginx
|
||||||
|
|
20
Route.php
20
Route.php
|
@ -1,5 +1,4 @@
|
||||||
<?PHP
|
<?php
|
||||||
|
|
||||||
class Route {
|
class Route {
|
||||||
|
|
||||||
private static $routes = Array();
|
private static $routes = Array();
|
||||||
|
@ -9,7 +8,7 @@ class Route{
|
||||||
/**
|
/**
|
||||||
* Function used to add a new route
|
* Function used to add a new route
|
||||||
* @param string $expression Route string or expression
|
* @param string $expression Route string or expression
|
||||||
* @param callable $function Function to call when route with allowed method is found
|
* @param callable $function Function to call if route with allowed method is found
|
||||||
* @param string|array $method Either a string of allowed method or an array with string values
|
* @param string|array $method Either a string of allowed method or an array with string values
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -30,9 +29,8 @@ class Route{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function run($basepath = '/', $case_matters = false, $trailing_slash_matters = false) {
|
public static function run($basepath = '/', $case_matters = false, $trailing_slash_matters = false) {
|
||||||
|
// Parse current URL
|
||||||
// Parse current url
|
$parsed_url = parse_url($_SERVER['REQUEST_URI']);
|
||||||
$parsed_url = parse_url($_SERVER['REQUEST_URI']);//Parse Uri
|
|
||||||
|
|
||||||
if (isset($parsed_url['path']) && $parsed_url['path'] != '/') {
|
if (isset($parsed_url['path']) && $parsed_url['path'] != '/') {
|
||||||
if ($trailing_slash_matters) {
|
if ($trailing_slash_matters) {
|
||||||
|
@ -66,18 +64,14 @@ class Route{
|
||||||
// Add 'find string end' automatically
|
// Add 'find string end' automatically
|
||||||
$route['expression'] = $route['expression'].'$';
|
$route['expression'] = $route['expression'].'$';
|
||||||
|
|
||||||
// echo $route['expression'].'<br/>';
|
|
||||||
|
|
||||||
// Check path match
|
// Check path match
|
||||||
if (preg_match('#'.$route['expression'].'#'.($case_matters ? '' : 'i'), $path, $matches)) {
|
if (preg_match('#'.$route['expression'].'#'.($case_matters ? '' : 'i'), $path, $matches)) {
|
||||||
|
|
||||||
$path_match_found = true;
|
$path_match_found = true;
|
||||||
|
|
||||||
// Cast allowed method to array if it's not one already, then run through all methods
|
// Cast allowed method to array if it's not one already, then run through all methods
|
||||||
foreach ((array)$route['method'] as $allowedMethod) {
|
foreach ((array)$route['method'] as $allowedMethod) {
|
||||||
// Check method match
|
// Check method match
|
||||||
if (strtolower($method) == strtolower($allowedMethod)) {
|
if (strtolower($method) == strtolower($allowedMethod)) {
|
||||||
|
|
||||||
array_shift($matches); // Always remove first element. This contains the whole string
|
array_shift($matches); // Always remove first element. This contains the whole string
|
||||||
|
|
||||||
if ($basepath != '' && $basepath != '/') {
|
if ($basepath != '' && $basepath != '/') {
|
||||||
|
@ -97,22 +91,20 @@ class Route{
|
||||||
|
|
||||||
// No matching route was found
|
// No matching route was found
|
||||||
if (!$route_match_found) {
|
if (!$route_match_found) {
|
||||||
|
|
||||||
// But a matching path exists
|
// But a matching path exists
|
||||||
if ($path_match_found) {
|
if ($path_match_found) {
|
||||||
header("HTTP/1.0 405 Method Not Allowed");
|
header('HTTP/1.0 405 Method Not Allowed');
|
||||||
if (self::$methodNotAllowed) {
|
if (self::$methodNotAllowed) {
|
||||||
call_user_func_array(self::$methodNotAllowed, Array($path,$method));
|
call_user_func_array(self::$methodNotAllowed, Array($path,$method));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
header("HTTP/1.0 404 Not Found");
|
header('HTTP/1.0 404 Not Found');
|
||||||
if (self::$pathNotFound) {
|
if (self::$pathNotFound) {
|
||||||
call_user_func_array(self::$pathNotFound, Array($path));
|
call_user_func_array(self::$pathNotFound, Array($path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
63
index.php
63
index.php
|
@ -1,8 +1,5 @@
|
||||||
<?PHP
|
<?php
|
||||||
|
echo <<<EOD
|
||||||
// This function just prints a simple navigation
|
|
||||||
function navi () {
|
|
||||||
?>
|
|
||||||
Navigation:
|
Navigation:
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="/">home</a></li>
|
<li><a href="/">home</a></li>
|
||||||
|
@ -20,111 +17,97 @@ function navi () {
|
||||||
<li><a href="/this-route-is-not-defined">404 Test</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>
|
<li><a href="/this-route-is-defined">405 Test</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<?PHP
|
EOD;
|
||||||
}
|
|
||||||
|
|
||||||
// Include router class
|
// Include router class
|
||||||
include('Route.php');
|
include 'Route.php';
|
||||||
|
|
||||||
// Add base route (startpage)
|
// Add base route (startpage)
|
||||||
Route::add('/', function() {
|
Route::add('/', function() {
|
||||||
navi();
|
|
||||||
echo 'Welcome :-)';
|
echo 'Welcome :-)';
|
||||||
});
|
});
|
||||||
|
|
||||||
// Another base route example
|
// Another base route example
|
||||||
Route::add('/index.php', function() {
|
Route::add('/index.php', function() {
|
||||||
navi();
|
echo 'You are not really on index.php ;-)';
|
||||||
echo 'You are not realy on index.php ;-)';
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Simple test route that simulates static html file
|
// Simple test route that simulates static html file
|
||||||
|
// TODO: Fix this for some web servers
|
||||||
Route::add('/test.html', function() {
|
Route::add('/test.html', function() {
|
||||||
navi();
|
|
||||||
echo 'Hello from test.html';
|
echo 'Hello from test.html';
|
||||||
});
|
});
|
||||||
|
|
||||||
// Post route example
|
// Post route example
|
||||||
Route::add('/contact-form', function() {
|
Route::add('/contact-form', function() {
|
||||||
navi();
|
echo '<form method="post"><input type="text" name="test"><input type="submit" value="send"></form>';
|
||||||
echo '<form method="post"><input type="text" name="test" /><input type="submit" value="send" /></form>';
|
|
||||||
}, 'get');
|
}, 'get');
|
||||||
|
|
||||||
// Post route example
|
// Post route example
|
||||||
Route::add('/contact-form', function() {
|
Route::add('/contact-form', function() {
|
||||||
navi();
|
echo 'Hey! The form has been sent:<br>';
|
||||||
echo 'Hey! The form has been sent:<br/>';
|
|
||||||
print_r($_POST);
|
print_r($_POST);
|
||||||
}, 'post');
|
}, 'post');
|
||||||
|
|
||||||
// Get and Post route example
|
// Get and Post route example
|
||||||
Route::add('/get-post-sample', function() {
|
Route::add('/get-post-sample', function() {
|
||||||
navi();
|
|
||||||
echo 'You can GET this page and also POST this form back to it';
|
echo 'You can GET this page and also POST this form back to it';
|
||||||
echo '<form method="post"><input type="text" name="input" /><input type="submit" value="send" /></form>';
|
echo '<form method="post"><input type="text" name="input"><input type="submit" value="send"></form>';
|
||||||
if(isset($_POST["input"])){
|
if (isset($_POST['input'])) {
|
||||||
echo 'I also received a POST with this data:<br/>';
|
echo 'I also received a POST with this data:<br>';
|
||||||
print_r($_POST);
|
print_r($_POST);
|
||||||
}
|
}
|
||||||
}, ['get','post']);
|
}, ['get','post']);
|
||||||
|
|
||||||
// Route with regexp parameter
|
// Route with regexp parameter
|
||||||
// Be aware that (.*) will match / (slash) too. For example: /user/foo/bar/edit
|
// 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 (.*)
|
// Also users could inject SQL statements 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
|
// You should better use a saver expression like /user/([0-9]*)/edit or /user/([A-Za-z]*)/edit
|
||||||
Route::add('/user/(.*)/edit', function($id) {
|
Route::add('/user/(.*)/edit', function($id) {
|
||||||
navi();
|
echo 'Edit user with id '.$id.'<br>';
|
||||||
echo 'Edit user with id '.$id.'<br/>';
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Accept only numbers as parameter. Other characters will result in a 404 error
|
// Accept only numbers as parameter. Other characters will result in a 404 error
|
||||||
Route::add('/foo/([0-9]*)/bar', function($var1) {
|
Route::add('/foo/([0-9]*)/bar', function($var1) {
|
||||||
navi();
|
|
||||||
echo $var1.' is a great number!';
|
echo $var1.' is a great number!';
|
||||||
});
|
});
|
||||||
|
|
||||||
// Crazy route with parameters
|
// Crazy route with parameters
|
||||||
Route::add('/(.*)/(.*)/(.*)/(.*)', function($var1,$var2,$var3,$var4) {
|
Route::add('/(.*)/(.*)/(.*)/(.*)', function($var1,$var2,$var3,$var4) {
|
||||||
navi();
|
echo 'This is the first match: '.$var1.' / '.$var2.' / '.$var3.' / '.$var4.'<br>';
|
||||||
echo 'This is the first match: '.$var1.' / '.$var2.' / '.$var3.' / '.$var4.'<br/>';
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Long route example
|
// Long route example
|
||||||
// This route gets never triggered because the route before matches too
|
// This route gets never triggered because the route before matches too
|
||||||
|
// TODO: Fix this; it'll get triggered
|
||||||
Route::add('/foo/bar/foo/bar', function() {
|
Route::add('/foo/bar/foo/bar', function() {
|
||||||
navi();
|
echo 'This is the second match <br>';
|
||||||
echo 'This is the second match <br/>';
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Trailing slash example
|
// Trailing slash example
|
||||||
Route::add('/aTrailingSlashDoesNotMatters',function(){
|
Route::add('/aTrailingSlashDoesNotMatter', function() {
|
||||||
navi();
|
echo 'a trailing slash does not matter<br>';
|
||||||
echo 'a trailing slash does not matters<br/>';
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Case example
|
// Case example
|
||||||
Route::add('/theCaseDoesNotMatters',function(){
|
Route::add('/theCaseDoesNotMatter',function(){
|
||||||
navi();
|
echo 'the case does not matter<br>';
|
||||||
echo 'the case does not matters<br/>';
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 405 test
|
// 405 test
|
||||||
Route::add('/this-route-is-defined', function() {
|
Route::add('/this-route-is-defined', function() {
|
||||||
navi();
|
|
||||||
echo 'You need to patch this route to see this content';
|
echo 'You need to patch this route to see this content';
|
||||||
}, 'patch');
|
}, 'patch');
|
||||||
|
|
||||||
// Add a 404 not found route
|
// Add a 404 not found route
|
||||||
Route::pathNotFound(function($path) {
|
Route::pathNotFound(function($path) {
|
||||||
navi();
|
echo 'Error 404 :-(<br>';
|
||||||
echo 'Error 404 :-(<br/>';
|
|
||||||
echo 'The requested path "'.$path.'" was not found!';
|
echo 'The requested path "'.$path.'" was not found!';
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add a 405 method not allowed route
|
// Add a 405 method not allowed route
|
||||||
Route::methodNotAllowed(function($path, $method) {
|
Route::methodNotAllowed(function($path, $method) {
|
||||||
navi();
|
echo 'Error 405 :-(<br>';
|
||||||
echo 'Error 405 :-(<br/>';
|
|
||||||
echo 'The requested path "'.$path.'" exists. But the request method "'.$method.'" is not allowed on this path!';
|
echo 'The requested path "'.$path.'" exists. But the request method "'.$method.'" is not allowed on this path!';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -138,5 +121,3 @@ Route::run('/');
|
||||||
|
|
||||||
// Enable case sensitive mode and trailing slashes by setting both to true
|
// Enable case sensitive mode and trailing slashes by setting both to true
|
||||||
// Route::run('/', true, true);
|
// Route::run('/', true, true);
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user