Merge pull request #237 from skipperbent/v3

V3
This commit is contained in:
Simon Sessingø
2017-05-09 07:06:33 +02:00
committed by GitHub
6 changed files with 133 additions and 34 deletions
+45 -13
View File
@@ -70,12 +70,13 @@ If you want a great new feature or experience any issues what-so-ever, please fe
- [Get all parameters](#get-all-parameters)
- [Advanced](#advanced)
- [Bootmanager: loading routes dynamically](#bootmanager-loading-routes-dynamically)
- [Url rewriting](#url-rewriting)
- [Rewrite using callback](#rewrite-using-callback)
- [Rewrite using url](#rewrite-using-url)
- [Adding routes manually](#adding-routes-manually)
- [Bootmanager: loading routes dynamically](#bootmanager-loading-routes-dynamically)
- [Adding routes manually](#adding-routes-manually)
- [Parameters](#parameters)
- [Custom default regex for matching parameters](#custom-default-regex-for-matching-parameters)
- [Extending](#extending)
- [Credits](#credits)
@@ -902,11 +903,9 @@ $request->setRewriteCallback('Example\MyCustomClass@hello');
$request->setRewriteUrl('/my-rewrite-url');
```
### Examples
**Note:** It's only possible to change the route BEFORE the route has initially been rendered. You can use the `Request` object to manipulate the route which are about to be loaded.
It's only possible to change the route BEFORE the route has initially been rendered. You can use the `Request` object to manipulate the route which are about to be loaded.
#### Rewrite using callback
### Rewrite using callback
This method is most efficient, as it will render the route immediately.
@@ -922,7 +921,7 @@ The example below will render `DefaultController@notFound` regardless of the url
**NOTE: Use this method if you want to load another controller. No additional middlewares or rules will be loaded.**
#### Middleware example
##### Middleware example
```php
namespace Demo\Middlewares;
@@ -942,7 +941,7 @@ class CustomMiddleware implements IMiddleware {
}
```
#### Exception handler example
##### Exception handler example
```php
namespace Demo\Handlers;
@@ -977,7 +976,7 @@ class CustomExceptionHandler implements IExceptionHandler
}
```
#### Rewrite using url
### Rewrite using url
The example below will cause the router to reload the request and reinitialize all the routes. This method is slower, but will ensure that all middlewares and rules for the route is loaded.
@@ -988,7 +987,7 @@ We are using the `url()` helper function to get the uri to another route added i
**NOTE: Use this method if you want to fully load another route using it's settings (request method, middlewares etc).**
#### Middleware example
##### Middleware example
The example below will redirect the request to the `home`-route.
@@ -1009,7 +1008,7 @@ class CustomMiddleware implements IMiddleware {
}
```
# Bootmanager: loading routes dynamically
### Bootmanager: loading routes dynamically
Sometimes it can be necessary to keep urls stored in the database, file or similar. In this example, we want the url ```/my-cat-is-beatiful``` to load the route ```/article/view/1``` which the router knows, because it's defined in the ```routes.php``` file.
@@ -1055,7 +1054,7 @@ The last thing we need to do, is to add our custom boot-manager to the ```routes
SimpleRouter::addBootManager(new CustomRouterRules());
```
## Adding routes manually
### Adding routes manually
The ```SimpleRouter``` class referenced in the previous example, is just a simple helper class that knows how to communicate with the ```Router``` class.
If you are up for a challenge, want the full control or simply just want to create your own ```Router``` helper class, this example is for you.
@@ -1081,6 +1080,39 @@ $route->setPrefix('v1');
$router->addRoute($route);
```
## Parameters
This section contains advanced tips & tricks on extending the usage for parameters.
### Custom default regex for matching parameters
By default simple-php-router uses the `\w` regular expression when matching parameters.
This decision was made with speed and reliability in mind, as this match will match both letters, number and most of the used symbols on the internet.
However, sometimes it can be nessesary to add a custom regular expression to match more advanced characters like `-` etc.
Instead of adding a custom regular expression to all your parameters, you can simply add a global regular expression which will be used on all the parameters on the route.
**Note:** If you the regular expression to be available across, we recommend using the global parameter on a group as demonstrated in the examples below.
#### Route
This example will ensure that all parameters use the `[\w\-]+` regular expression when parsing.
```php
SimpleRouter::get('/path/{parameter}', 'VideoController@home', ['defaultParameterRegex' => '[\w\-]+']);
```
You can also apply this setting to a group if you need multiple routes to use your custom regular expression when parsing parameters.
```php
SimpleRouter::group(['defaultParameterRegex' => '[\w\-]+'], function() {
SimpleRouter::get('/path/{parameter}', 'VideoController@home');
});
```
## Extending
This is a simple example of an integration into a framework.
+3 -12
View File
@@ -1,4 +1,5 @@
<?php
namespace Pecee\SimpleRouter\Route;
use Pecee\Http\Middleware\IMiddleware;
@@ -54,17 +55,7 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
return null;
}
$parameters = [];
if (preg_match($this->regex, $request->getHost() . $url, $parameters) > 0) {
/* Remove global match */
$this->parameters = array_slice($parameters, 1);
return true;
}
return false;
return (preg_match($this->regex, $request->getHost() . $url) > 0);
}
/**
@@ -79,7 +70,7 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
if (strpos($this->url, $this->paramModifiers[0]) !== false) {
$regex = sprintf(static::PARAMETERS_REGEX_MATCH, $this->paramModifiers[0], $this->paramOptionalSymbol, $this->paramModifiers[1]);
$regex = sprintf(static::PARAMETERS_REGEX_FORMAT, $this->paramModifiers[0], $this->paramOptionalSymbol, $this->paramModifiers[1]);
if (preg_match_all('/' . $regex . '/', $this->url, $matches)) {
$this->parameters = array_fill_keys($matches[1], null);
+53 -5
View File
@@ -1,4 +1,5 @@
<?php
namespace Pecee\SimpleRouter\Route;
use Pecee\Http\Request;
@@ -6,7 +7,8 @@ use Pecee\SimpleRouter\Exceptions\NotFoundHttpException;
abstract class Route implements IRoute
{
const PARAMETERS_REGEX_MATCH = '%s([\w]+)(\%s?)%s';
const PARAMETERS_REGEX_FORMAT = '%s([\w]+)(\%s?)%s';
const PARAMETERS_DEFAULT_REGEX = '[\w]+';
const REQUEST_TYPE_GET = 'get';
const REQUEST_TYPE_POST = 'post';
@@ -31,6 +33,7 @@ abstract class Route implements IRoute
* @var bool
*/
protected $filterEmptyParams = false;
protected $defaultParameterRegex = null;
protected $paramModifiers = '{}';
protected $paramOptionalSymbol = '?';
protected $group;
@@ -94,9 +97,9 @@ abstract class Route implements IRoute
}
}
protected function parseParameters($route, $url, $parameterRegex = '[\w]+')
protected function parseParameters($route, $url, $parameterRegex = null)
{
$regex = sprintf(static::PARAMETERS_REGEX_MATCH, $this->paramModifiers[0], $this->paramOptionalSymbol, $this->paramModifiers[1]);
$regex = sprintf(static::PARAMETERS_REGEX_FORMAT, $this->paramModifiers[0], $this->paramOptionalSymbol, $this->paramModifiers[1]);
$parameters = [];
@@ -111,7 +114,20 @@ abstract class Route implements IRoute
if ($key < count($parameters[1])) {
$name = $parameters[1][$key];
$regex = isset($this->where[$name]) ? $this->where[$name] : $parameterRegex;
/* If custom regex is defined, use that */
if (isset($this->where[$name]) === true) {
$regex = $this->where[$name];
} else {
/* If method specific regex is defined use that, otherwise use the default parameter regex */
if ($parameterRegex !== null) {
$regex = $parameterRegex;
} else {
$regex = ($this->defaultParameterRegex === null) ? static::PARAMETERS_DEFAULT_REGEX : $this->defaultParameterRegex;
}
}
$regex = sprintf('\-?\/?(?P<%s>%s)', $name, $regex) . $parameters[2][$key];
}
@@ -129,7 +145,7 @@ abstract class Route implements IRoute
$values = [];
if (isset($parameters[1])) {
if (isset($parameters[1]) === true) {
/* Only take matched parameters with name */
foreach ($parameters[1] as $name) {
@@ -343,6 +359,10 @@ abstract class Route implements IRoute
$values['middleware'] = $this->middlewares;
}
if ($this->defaultParameterRegex !== null) {
$values['defaultParameterRegex'] = $this->defaultParameterRegex;
}
return $values;
}
@@ -376,6 +396,10 @@ abstract class Route implements IRoute
$this->setMiddlewares(array_merge((array)$values['middleware'], $this->middlewares));
}
if (isset($values['defaultParameterRegex'])) {
$this->setDefaultParameterRegex($values['defaultParameterRegex']);
}
return $this;
}
@@ -487,4 +511,28 @@ abstract class Route implements IRoute
return $this->middlewares;
}
/**
* Set default regular expression used when matching parameters.
* This is used when no custom parameter regex is found.
*
* @param string $regex
* @return static $this
*/
public function setDefaultParameterRegex($regex)
{
$this->defaultParameterRegex = $regex;
return $this;
}
/**
* Get default regular expression used when matching parameters.
*
* @return string
*/
public function getDefaultParameterRegex()
{
return $this->defaultParameterRegex;
}
}
@@ -1,4 +1,5 @@
<?php
namespace Pecee\SimpleRouter\Route;
use Pecee\Http\Request;
@@ -90,8 +91,11 @@ class RouteResource extends LoadableRoute implements IControllerRoute
$route = rtrim($this->url, '/') . '/{id?}/{action?}';
/* Parse parameters from current route */
$this->parameters = $this->parseParameters($route, $url);
if ($this->parameters === null) {
/* If no custom regular expression or parameters was found on this route, we stop */
if ($regexMatch === null && $this->parameters === null) {
return false;
}
+8 -3
View File
@@ -1,4 +1,5 @@
<?php
namespace Pecee\SimpleRouter\Route;
use Pecee\Http\Request;
@@ -18,17 +19,21 @@ class RouteUrl extends LoadableRoute
/* Match global regular-expression for route */
$regexMatch = $this->matchRegex($request, $url);
if ($regexMatch === false) {
return false;
}
/* Make regular expression based on route */
/* Parse parameters from current route */
$parameters = $this->parseParameters($this->url, $url);
if ($parameters === null) {
/* If no custom regular expression or parameters was found on this route, we stop */
if ($regexMatch === null && $parameters === null) {
return false;
}
$this->setParameters($parameters);
/* Set the parameters */
$this->setParameters((array)$parameters);
return true;
}
+19
View File
@@ -125,4 +125,23 @@ class RouterRouteTest extends PHPUnit_Framework_TestCase
TestRouter::debug('/my/custom-path', 'get');
}
public function testDefaultParameterRegex()
{
TestRouter::get('/my/{path}', 'DummyController@param', ['defaultParameterRegex' => '[\w\-]+']);
$output = TestRouter::debugOutput('/my/custom-regex', 'get');
$this->assertEquals('custom-regex', $output);
}
public function testDefaultParameterRegexGroup()
{
TestRouter::group(['defaultParameterRegex' => '[\w\-]+'], function() {
TestRouter::get('/my/{path}', 'DummyController@param');
});
$output = TestRouter::debugOutput('/my/custom-regex', 'get');
$this->assertEquals('custom-regex', $output);
}
}