mirror of
https://github.com/skipperbent/simple-php-router.git
synced 2026-07-01 15:29:58 +00:00
Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 253c0c70d4 | |||
| 115c8e510a | |||
| 53ba2d7ac5 | |||
| 35ee79d02c | |||
| 315fe05769 | |||
| 6306b604e8 | |||
| 4dd0739df9 | |||
| a57113309a | |||
| 0bd234d996 | |||
| 27d24758b1 | |||
| 4d08f08c68 | |||
| aeacda1812 | |||
| 765204f552 | |||
| 4267cb8751 | |||
| 714edf7902 | |||
| c3b12ba053 | |||
| b096742d6b | |||
| 3298970798 | |||
| bb6f56ef8c | |||
| 6c675124fa | |||
| 14a030294e | |||
| 8bc8124366 | |||
| 1332ef7139 | |||
| 12bbc98a82 | |||
| 69b0f4320e | |||
| 4c60055c7e | |||
| 89aeeeb593 | |||
| 849749969d | |||
| c37a7159d2 | |||
| df2545dd37 | |||
| bd0a6af41f | |||
| 3510c4c5a4 |
@@ -270,6 +270,24 @@ Register the new class in your ```routes.php```, custom ```Router``` class or wh
|
|||||||
SimpleRouter::csrfVerifier(new \Demo\Middleware\CsrfVerifier());
|
SimpleRouter::csrfVerifier(new \Demo\Middleware\CsrfVerifier());
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Easily overwrite route about to be loaded
|
||||||
|
Sometimes it can be useful to manipulate the route that's about to be loaded, for instance if a user is not authenticated or if an error occurred within your Middleware that requires
|
||||||
|
some other route to be initialised. Simple PHP Router allows you to easily change the route about to be executed. All information about the current route is stored in
|
||||||
|
the ```\Pecee\SimpleRouter\Http\Request``` object.
|
||||||
|
|
||||||
|
**Note:** Please note that it's only possible to change the route BEFORE any route has initially been loaded, so doing this in your custom ExceptionHandler or Middleware is highly recommended.
|
||||||
|
|
||||||
|
```php
|
||||||
|
$route = Request::getInstance()->getLoadedRoute();
|
||||||
|
|
||||||
|
$route->setCallback('Example\MyCustomClass@hello');
|
||||||
|
|
||||||
|
// -- or --
|
||||||
|
|
||||||
|
$route->setClass('Example\MyCustomClass');
|
||||||
|
$route->setMethod('hello');
|
||||||
|
```
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
While I work on a better documentation, please refer to the Laravel 5 routing documentation here:
|
While I work on a better documentation, please refer to the Laravel 5 routing documentation here:
|
||||||
|
|
||||||
@@ -278,6 +296,9 @@ http://laravel.com/docs/5.1/routing
|
|||||||
## Easily extendable
|
## Easily extendable
|
||||||
The router can be easily extended to customize your needs.
|
The router can be easily extended to customize your needs.
|
||||||
|
|
||||||
|
## Ideas and issues
|
||||||
|
If you want a great new feature or experience any issues what-so-ever, please feel free to leave an issue and i'll look into it whenever possible.
|
||||||
|
|
||||||
## The MIT License (MIT)
|
## The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2015 Simon Sessingø / simple-php-router
|
Copyright (c) 2015 Simon Sessingø / simple-php-router
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Pecee\Http;
|
namespace Pecee\Http;
|
||||||
|
|
||||||
|
use Pecee\SimpleRouter\RouterBase;
|
||||||
|
|
||||||
class Request {
|
class Request {
|
||||||
|
|
||||||
protected static $instance;
|
protected static $instance;
|
||||||
@@ -10,6 +12,7 @@ class Request {
|
|||||||
protected $host;
|
protected $host;
|
||||||
protected $method;
|
protected $method;
|
||||||
protected $headers;
|
protected $headers;
|
||||||
|
protected $loadedRoute;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return new instance
|
* Return new instance
|
||||||
@@ -27,7 +30,17 @@ class Request {
|
|||||||
$this->host = $_SERVER['HTTP_HOST'];
|
$this->host = $_SERVER['HTTP_HOST'];
|
||||||
$this->uri = $_SERVER['REQUEST_URI'];
|
$this->uri = $_SERVER['REQUEST_URI'];
|
||||||
$this->method = (isset($_POST['_method'])) ? strtolower($_POST['_method']) : strtolower($_SERVER['REQUEST_METHOD']);
|
$this->method = (isset($_POST['_method'])) ? strtolower($_POST['_method']) : strtolower($_SERVER['REQUEST_METHOD']);
|
||||||
$this->headers = array_change_key_case(getallheaders(), CASE_LOWER);
|
$this->headers = $this->getAllHeaders();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getAllHeaders() {
|
||||||
|
$headers = array();
|
||||||
|
foreach ($_SERVER as $name => $value) {
|
||||||
|
if (substr($name, 0, 5) === 'HTTP_') {
|
||||||
|
$headers[strtolower(str_replace('_', '-', substr($name, 5)))] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getIsSecure() {
|
public function getIsSecure() {
|
||||||
@@ -130,4 +143,12 @@ class Request {
|
|||||||
return isset($this->data[$name]) ? $this->data[$name] : null;
|
return isset($this->data[$name]) ? $this->data[$name] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the currently loaded route.
|
||||||
|
* @return \Pecee\SimpleRouter\RouterEntry
|
||||||
|
*/
|
||||||
|
public function getLoadedRoute() {
|
||||||
|
return $this->loadedRoute;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -15,7 +15,6 @@ class RouterBase {
|
|||||||
protected $processedRoutes;
|
protected $processedRoutes;
|
||||||
protected $controllerUrlMap;
|
protected $controllerUrlMap;
|
||||||
protected $backStack;
|
protected $backStack;
|
||||||
protected $loadedRoute;
|
|
||||||
protected $defaultNamespace;
|
protected $defaultNamespace;
|
||||||
protected $baseCsrfVerifier;
|
protected $baseCsrfVerifier;
|
||||||
|
|
||||||
@@ -54,7 +53,10 @@ class RouterBase {
|
|||||||
$route = $routes[$i];
|
$route = $routes[$i];
|
||||||
|
|
||||||
$route->addSettings($settings);
|
$route->addSettings($settings);
|
||||||
$route->setGroup($group);
|
|
||||||
|
if($backStack) {
|
||||||
|
$route->setGroup($group);
|
||||||
|
}
|
||||||
|
|
||||||
if($this->defaultNamespace && !$route->getNamespace()) {
|
if($this->defaultNamespace && !$route->getNamespace()) {
|
||||||
$namespace = null;
|
$namespace = null;
|
||||||
@@ -124,6 +126,12 @@ class RouterBase {
|
|||||||
|
|
||||||
$route = $this->controllerUrlMap[$i];
|
$route = $this->controllerUrlMap[$i];
|
||||||
|
|
||||||
|
if($route->getGroup() !== null) {
|
||||||
|
if($route->getGroup()->matchDomain($this->request) === false) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$routeMatch = $route->matchRoute($this->request);
|
$routeMatch = $route->matchRoute($this->request);
|
||||||
|
|
||||||
if($routeMatch) {
|
if($routeMatch) {
|
||||||
@@ -133,17 +141,12 @@ class RouterBase {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($route->getGroup() !== null) {
|
|
||||||
if($route->getGroup()->matchDomain($this->request) === false) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$routeNotAllowed = false;
|
$routeNotAllowed = false;
|
||||||
|
|
||||||
$this->loadedRoute = $route;
|
$this->request->loadedRoute = $route;
|
||||||
$route->loadMiddleware($this->request);
|
$route->loadMiddleware($this->request);
|
||||||
$route->renderRoute($this->request);
|
|
||||||
|
$this->request->loadedRoute->renderRoute($this->request);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -152,7 +155,7 @@ class RouterBase {
|
|||||||
throw new RouterException('Route or method not allowed', 403);
|
throw new RouterException('Route or method not allowed', 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$this->loadedRoute) {
|
if(!$this->request->loadedRoute) {
|
||||||
throw new RouterException(sprintf('Route not found: %s', $this->request->getUri()), 404);
|
throw new RouterException(sprintf('Route not found: %s', $this->request->getUri()), 404);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -175,8 +178,8 @@ class RouterBase {
|
|||||||
* @return RouterEntry
|
* @return RouterEntry
|
||||||
*/
|
*/
|
||||||
public function getLoadedRoute() {
|
public function getLoadedRoute() {
|
||||||
if(!($this->loadedRoute instanceof RouterGroup)) {
|
if(!($this->request->loadedRoute instanceof RouterGroup)) {
|
||||||
return $this->loadedRoute;
|
return $this->request->loadedRoute;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -324,6 +327,10 @@ class RouterBase {
|
|||||||
return $url;
|
return $url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($controller === null && $this->request->loadedRoute !== null) {
|
||||||
|
return $this->processUrl($this->request->loadedRoute, $this->request->loadedRoute->getMethod(), $parameters, $getParams);
|
||||||
|
}
|
||||||
|
|
||||||
$c = '';
|
$c = '';
|
||||||
$method = null;
|
$method = null;
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class RouterController extends RouterEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function matchRoute(Request $request) {
|
public function matchRoute(Request $request) {
|
||||||
$url = parse_url($request->getUri());
|
$url = parse_url(urldecode($request->getUri()));
|
||||||
$url = rtrim($url['path'], '/') . '/';
|
$url = rtrim($url['path'], '/') . '/';
|
||||||
|
|
||||||
if(strtolower($url) == strtolower($this->url) || stripos($url, $this->url) === 0) {
|
if(strtolower($url) == strtolower($this->url) || stripos($url, $this->url) === 0) {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ abstract class RouterEntry {
|
|||||||
public function __construct() {
|
public function __construct() {
|
||||||
$this->settings = array();
|
$this->settings = array();
|
||||||
$this->settings['requestMethods'] = array();
|
$this->settings['requestMethods'] = array();
|
||||||
$this->settings['parametersRegex'] = array();
|
$this->settings['where'] = array();
|
||||||
$this->settings['parameters'] = array();
|
$this->settings['parameters'] = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,6 +77,16 @@ abstract class RouterEntry {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setMethod($method) {
|
||||||
|
$this->callback = sprintf('%s@%s', $this->getClass(), $method);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setClass($class) {
|
||||||
|
$this->callback = sprintf('%s@%s', $class, $this->getMethod());
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $prefix
|
* @param string $prefix
|
||||||
* @return self
|
* @return self
|
||||||
@@ -155,7 +165,7 @@ abstract class RouterEntry {
|
|||||||
* @return self
|
* @return self
|
||||||
*/
|
*/
|
||||||
public function where(array $options) {
|
public function where(array $options) {
|
||||||
$this->parametersRegex = array_merge($this->parametersRegex, $options);
|
$this->where = array_merge($this->where, $options);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,10 +188,6 @@ abstract class RouterEntry {
|
|||||||
public function getMergeableSettings() {
|
public function getMergeableSettings() {
|
||||||
$settings = $this->settings;
|
$settings = $this->settings;
|
||||||
|
|
||||||
/*if(isset($settings['middleware'])) {
|
|
||||||
unset($settings['middleware']);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if(isset($settings['prefix'])) {
|
if(isset($settings['prefix'])) {
|
||||||
unset($settings['prefix']);
|
unset($settings['prefix']);
|
||||||
}
|
}
|
||||||
@@ -242,18 +248,13 @@ abstract class RouterEntry {
|
|||||||
return new $name();
|
return new $name();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function parseParameters($route, $url, $parameterRegex = '[a-z0-9]*?') {
|
protected function parseParameters($route, $url, $parameterRegex = '[a-z0-9]+') {
|
||||||
$parameterNames = array();
|
$parameterNames = array();
|
||||||
$regex = '';
|
$regex = '';
|
||||||
$lastCharacter = '';
|
$lastCharacter = '';
|
||||||
$isParameter = false;
|
$isParameter = false;
|
||||||
$parameter = '';
|
$parameter = '';
|
||||||
|
|
||||||
// Use custom parameter regex if it exists
|
|
||||||
if(is_array($this->parametersRegex) && isset($this->parametersRegex[$parameter])) {
|
|
||||||
$parameterRegex = $this->parametersRegex[$parameter];
|
|
||||||
}
|
|
||||||
|
|
||||||
$routeLength = strlen($route);
|
$routeLength = strlen($route);
|
||||||
for($i = 0; $i < $routeLength; $i++) {
|
for($i = 0; $i < $routeLength; $i++) {
|
||||||
|
|
||||||
@@ -275,12 +276,18 @@ abstract class RouterEntry {
|
|||||||
} elseif($isParameter && $character === '}') {
|
} elseif($isParameter && $character === '}') {
|
||||||
$required = true;
|
$required = true;
|
||||||
// Check for optional parameter
|
// Check for optional parameter
|
||||||
|
|
||||||
|
// Use custom parameter regex if it exists
|
||||||
|
if(is_array($this->where) && isset($this->where[$parameter])) {
|
||||||
|
$parameterRegex = $this->where[$parameter];
|
||||||
|
}
|
||||||
|
|
||||||
if($lastCharacter === '?') {
|
if($lastCharacter === '?') {
|
||||||
$parameter = substr($parameter, 0, strlen($parameter)-1);
|
$parameter = substr($parameter, 0, strlen($parameter)-1);
|
||||||
$regex .= '(?:(?:\/{0,1}(?P<'.$parameter.'>[^\/]*)))\\/{0,1}';
|
$regex .= '(?:\\/?(?P<'.$parameter.'>[^\/]+)?\\/?)';
|
||||||
$required = false;
|
$required = false;
|
||||||
} else {
|
} else {
|
||||||
$regex .= '(?:\\/{0,1}(?P<' . $parameter . '>'. $parameterRegex .')\\/{0,1})';
|
$regex .= '\\/(?P<' . $parameter . '>'. $parameterRegex .')\\/';
|
||||||
}
|
}
|
||||||
$parameterNames[] = array('name' => $parameter, 'required' => $required);
|
$parameterNames[] = array('name' => $parameter, 'required' => $required);
|
||||||
$parameter = '';
|
$parameter = '';
|
||||||
@@ -313,6 +320,10 @@ abstract class RouterEntry {
|
|||||||
throw new RouterException('Missing required parameter ' . $name['name'], 404);
|
throw new RouterException('Missing required parameter ' . $name['name'], 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!$name['required'] && $parameterValue === null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$parameters[$name['name']] = $parameterValue;
|
$parameters[$name['name']] = $parameterValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -365,7 +376,11 @@ abstract class RouterEntry {
|
|||||||
throw new RouterException(sprintf('Method %s does not exist in class %s', $method, $className), 404);
|
throw new RouterException(sprintf('Method %s does not exist in class %s', $method, $className), 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
call_user_func_array(array($class, $method), $this->getParameters());
|
$parameters = array_filter($this->getParameters(), function($var){
|
||||||
|
return !is_null($var);
|
||||||
|
});
|
||||||
|
|
||||||
|
call_user_func_array(array($class, $method), $parameters);
|
||||||
|
|
||||||
return $class;
|
return $class;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class RouterGroup extends RouterEntry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$parameters = $this->parseParameters($this->domain, $request->getHost(), '[^.]*');
|
$parameters = $this->parseParameters($this->domain, $request->getHost(), '[^.]*');
|
||||||
@@ -38,10 +38,10 @@ class RouterGroup extends RouterEntry {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function renderRoute(Request $request) {
|
public function renderRoute(Request $request) {
|
||||||
|
|||||||
@@ -46,12 +46,12 @@ class RouterResource extends RouterEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function matchRoute(Request $request) {
|
public function matchRoute(Request $request) {
|
||||||
$url = parse_url($request->getUri());
|
$url = parse_url(urldecode($request->getUri()));
|
||||||
$url = rtrim($url['path'], '/') . '/';
|
$url = rtrim($url['path'], '/') . '/';
|
||||||
|
|
||||||
$route = rtrim($this->url, '/') . '/{id?}/{action?}';
|
$route = rtrim($this->url, '/') . '/{id?}/{action?}';
|
||||||
|
|
||||||
$parameters = $this->parseParameters($route, $url, '[0-9]*?');
|
$parameters = $this->parseParameters($route, $url, '[0-9]+?');
|
||||||
|
|
||||||
if($parameters !== null) {
|
if($parameters !== null) {
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ class RouterResource extends RouterEntry {
|
|||||||
$parameters = array_merge($this->parameters, $parameters);
|
$parameters = array_merge($this->parameters, $parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
$action = $parameters['action'];
|
$action = isset($parameters['action']) ? $parameters['action'] : null;
|
||||||
unset($parameters['action']);
|
unset($parameters['action']);
|
||||||
|
|
||||||
// Delete
|
// Delete
|
||||||
@@ -88,7 +88,7 @@ class RouterResource extends RouterEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Show
|
// Show
|
||||||
if($action && $this->postMethod === self::REQUEST_TYPE_GET) {
|
if(isset($parameters['id']) && $this->postMethod === self::REQUEST_TYPE_GET) {
|
||||||
return $this->call('show', $parameters);
|
return $this->call('show', $parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace Pecee\SimpleRouter;
|
namespace Pecee\SimpleRouter;
|
||||||
|
|
||||||
|
use Pecee\ArrayUtil;
|
||||||
use Pecee\Http\Request;
|
use Pecee\Http\Request;
|
||||||
|
|
||||||
class RouterRoute extends RouterEntry {
|
class RouterRoute extends RouterEntry {
|
||||||
@@ -20,7 +21,7 @@ class RouterRoute extends RouterEntry {
|
|||||||
|
|
||||||
public function matchRoute(Request $request) {
|
public function matchRoute(Request $request) {
|
||||||
|
|
||||||
$url = parse_url($request->getUri());
|
$url = parse_url(urldecode($request->getUri()));
|
||||||
$url = rtrim($url['path'], '/') . '/';
|
$url = rtrim($url['path'], '/') . '/';
|
||||||
|
|
||||||
// Match on custom defined regular expression
|
// Match on custom defined regular expression
|
||||||
@@ -49,6 +50,8 @@ class RouterRoute extends RouterEntry {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +77,7 @@ class RouterRoute extends RouterEntry {
|
|||||||
if(count($parameters)) {
|
if(count($parameters)) {
|
||||||
$tmp = array();
|
$tmp = array();
|
||||||
foreach($parameters as $param) {
|
foreach($parameters as $param) {
|
||||||
$tmp[$param] = '';
|
$tmp[$param] = null;
|
||||||
}
|
}
|
||||||
$this->parameters = $tmp;
|
$this->parameters = $tmp;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user