mirror of
https://github.com/skipperbent/simple-php-router.git
synced 2026-06-15 18:23:26 +03:00
Merge pull request #498 from skipperbent/v4-array-callback
[FEATURE] Added support for class hinting on routes as requested by #491
This commit is contained in:
12
.idea/workspace.xml
generated
12
.idea/workspace.xml
generated
@@ -6,7 +6,14 @@
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="a7058529-bdc4-40b4-a50d-c50564dc83f0" name="Default" comment="">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/Pecee/Http/Input/InputItem.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/Pecee/Http/Input/InputItem.php" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/IRoute.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/IRoute.php" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/Route.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/Route.php" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/RouteController.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/RouteController.php" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/RouteResource.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/RouteResource.php" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/Pecee/SimpleRouter/SimpleRouter.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/Pecee/SimpleRouter/SimpleRouter.php" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/tests/Pecee/SimpleRouter/RouterRouteTest.php" beforeDir="false" afterPath="$PROJECT_DIR$/tests/Pecee/SimpleRouter/RouterRouteTest.php" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/tests/Pecee/SimpleRouter/RouterUrlTest.php" beforeDir="false" afterPath="$PROJECT_DIR$/tests/Pecee/SimpleRouter/RouterUrlTest.php" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
@@ -426,6 +433,8 @@
|
||||
<workItem from="1616030812009" duration="3745000" />
|
||||
<workItem from="1616076234772" duration="377000" />
|
||||
<workItem from="1616086876180" duration="6839000" />
|
||||
<workItem from="1616147368571" duration="141000" />
|
||||
<workItem from="1616286180427" duration="3108000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
@@ -525,6 +534,7 @@
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
<option name="oldMeFiltersMigrated" value="true" />
|
||||
</component>
|
||||
<component name="XSLT-Support.FileAssociations.UIState">
|
||||
<expand />
|
||||
|
||||
17
README.md
17
README.md
@@ -33,6 +33,7 @@ You can donate any amount of your choice by [clicking here](https://www.paypal.c
|
||||
- [Helper functions](#helper-functions)
|
||||
- [Routes](#routes)
|
||||
- [Basic routing](#basic-routing)
|
||||
- [Class hinting](#class-hinting)
|
||||
- [Available methods](#available-methods)
|
||||
- [Multiple HTTP-verbs](#multiple-http-verbs)
|
||||
- [Route parameters](#route-parameters)
|
||||
@@ -404,6 +405,14 @@ SimpleRouter::get('/', function() {
|
||||
});
|
||||
```
|
||||
|
||||
### Class hinting
|
||||
|
||||
You can use class hinting to load a class & method like this:
|
||||
|
||||
```php
|
||||
SimpleRouter::get('/', [MyClass::class, 'myMethod']);
|
||||
```
|
||||
|
||||
### Available methods
|
||||
|
||||
Here you can see a list over all available routes:
|
||||
@@ -785,12 +794,17 @@ SimpleRouter::group(['middleware' => \Demo\Middlewares\Site::class, 'exceptionHa
|
||||
|
||||
SimpleRouter::get('/answers/{id}', 'ControllerAnswers@show', ['where' => ['id' => '[0-9]+']]);
|
||||
|
||||
/**
|
||||
* Class hinting is supported too
|
||||
*/
|
||||
|
||||
SimpleRouter::get('/answers/{id}', [ControllerAnswers::class, 'show'], ['where' => ['id' => '[0-9]+']]);
|
||||
|
||||
/**
|
||||
* Restful resource (see IRestController interface for available methods)
|
||||
*/
|
||||
|
||||
SimpleRouter::resource('/rest', ControllerRessource::class);
|
||||
SimpleRouter::resource('/rest', ControllerResource::class);
|
||||
|
||||
|
||||
/**
|
||||
@@ -811,7 +825,6 @@ SimpleRouter::group(['middleware' => \Demo\Middlewares\Site::class, 'exceptionHa
|
||||
});
|
||||
|
||||
SimpleRouter::get('/page/404', 'ControllerPage@notFound', ['as' => 'page.notfound']);
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -82,7 +82,7 @@ interface IRoute
|
||||
/**
|
||||
* Set callback
|
||||
*
|
||||
* @param string $callback
|
||||
* @param string|array|\Closure $callback
|
||||
* @return static
|
||||
*/
|
||||
public function setCallback($callback): self;
|
||||
|
||||
@@ -95,26 +95,22 @@ abstract class Route implements IRoute
|
||||
$router->debug('Executing callback');
|
||||
|
||||
/* When the callback is a function */
|
||||
|
||||
return $router->getClassLoader()->loadClosure($callback, $parameters);
|
||||
}
|
||||
|
||||
/* When the callback is a class + method */
|
||||
$controller = explode('@', $callback);
|
||||
$controller = $this->getClass();
|
||||
$method = $this->getMethod();
|
||||
|
||||
$namespace = $this->getNamespace();
|
||||
|
||||
$className = ($namespace !== null && $controller[0][0] !== '\\') ? $namespace . '\\' . $controller[0] : $controller[0];
|
||||
$className = ($namespace !== null && $controller[0] !== '\\') ? $namespace . '\\' . $controller : $controller;
|
||||
|
||||
$router->debug('Loading class %s', $className);
|
||||
$class = $router->getClassLoader()->loadClass($className);
|
||||
|
||||
if (\count($controller) === 1) {
|
||||
if ($method === null) {
|
||||
$controller[1] = '__invoke';
|
||||
}
|
||||
|
||||
$method = $controller[1];
|
||||
|
||||
if (method_exists($class, $method) === false) {
|
||||
throw new NotFoundHttpException(sprintf('Method "%s" does not exist in class "%s"', $method, $className), 404);
|
||||
}
|
||||
@@ -271,7 +267,7 @@ abstract class Route implements IRoute
|
||||
/**
|
||||
* Set callback
|
||||
*
|
||||
* @param string $callback
|
||||
* @param string|array\Closure $callback
|
||||
* @return static
|
||||
*/
|
||||
public function setCallback($callback): IRoute
|
||||
@@ -291,6 +287,10 @@ abstract class Route implements IRoute
|
||||
|
||||
public function getMethod(): ?string
|
||||
{
|
||||
if(\is_array($this->callback) === true && \count($this->callback) > 1) {
|
||||
return $this->callback[1];
|
||||
}
|
||||
|
||||
if (\is_string($this->callback) === true && strpos($this->callback, '@') !== false) {
|
||||
$tmp = explode('@', $this->callback);
|
||||
|
||||
@@ -302,9 +302,12 @@ abstract class Route implements IRoute
|
||||
|
||||
public function getClass(): ?string
|
||||
{
|
||||
if(\is_array($this->callback) === true && \count($this->callback) > 0) {
|
||||
return $this->callback[0];
|
||||
}
|
||||
|
||||
if (\is_string($this->callback) === true && strpos($this->callback, '@') !== false) {
|
||||
$tmp = explode('@', $this->callback);
|
||||
|
||||
return $tmp[0];
|
||||
}
|
||||
|
||||
@@ -313,15 +316,13 @@ abstract class Route implements IRoute
|
||||
|
||||
public function setMethod(string $method): IRoute
|
||||
{
|
||||
$this->callback = sprintf('%s@%s', $this->getClass(), $method);
|
||||
|
||||
$this->callback = [$this->getClass(), $method];
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setClass(string $class): IRoute
|
||||
{
|
||||
$this->callback = sprintf('%s@%s', $class, $this->getMethod());
|
||||
|
||||
$this->callback = [$class, $this->getMethod()];
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ class RouteController extends LoadableRoute implements IControllerRoute
|
||||
$this->parameters = \array_slice($path, 1);
|
||||
|
||||
// Set callback
|
||||
$this->setCallback($this->controller . '@' . $this->method);
|
||||
$this->setCallback([$this->controller, $this->method]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ class RouteResource extends LoadableRoute implements IControllerRoute
|
||||
|
||||
protected function call($method): bool
|
||||
{
|
||||
$this->setCallback($this->controller . '@' . $method);
|
||||
$this->setCallback([$this->controller, $method]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ namespace Pecee\SimpleRouter;
|
||||
|
||||
use DI\Container;
|
||||
use Pecee\Exceptions\InvalidArgumentException;
|
||||
use Pecee\Http\Exceptions\MalformedUrlException;
|
||||
use Pecee\Http\Middleware\BaseCsrfVerifier;
|
||||
use Pecee\Http\Request;
|
||||
use Pecee\Http\Response;
|
||||
@@ -178,7 +177,7 @@ class SimpleRouter
|
||||
* Route the given url to your callback on GET request method.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param string|array|\Closure $callback
|
||||
* @param array|null $settings
|
||||
*
|
||||
* @return RouteUrl
|
||||
@@ -192,7 +191,7 @@ class SimpleRouter
|
||||
* Route the given url to your callback on POST request method.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param string|array|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouteUrl
|
||||
*/
|
||||
@@ -205,7 +204,7 @@ class SimpleRouter
|
||||
* Route the given url to your callback on PUT request method.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param string|array|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouteUrl
|
||||
*/
|
||||
@@ -218,7 +217,7 @@ class SimpleRouter
|
||||
* Route the given url to your callback on PATCH request method.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param string|array|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouteUrl
|
||||
*/
|
||||
@@ -231,7 +230,7 @@ class SimpleRouter
|
||||
* Route the given url to your callback on OPTIONS request method.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param string|array|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouteUrl
|
||||
*/
|
||||
@@ -244,7 +243,7 @@ class SimpleRouter
|
||||
* Route the given url to your callback on DELETE request method.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param string|array|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouteUrl
|
||||
*/
|
||||
@@ -307,7 +306,7 @@ class SimpleRouter
|
||||
* Alias for the form method
|
||||
*
|
||||
* @param string $url
|
||||
* @param callable $callback
|
||||
* @param string|array|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @see SimpleRouter::form
|
||||
* @return RouteUrl
|
||||
@@ -322,7 +321,7 @@ class SimpleRouter
|
||||
* Route the given url to your callback on POST and GET request method.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param string|array|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @see SimpleRouter::form
|
||||
* @return RouteUrl
|
||||
@@ -337,7 +336,7 @@ class SimpleRouter
|
||||
*
|
||||
* @param array $requestMethods
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param string|array|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouteUrl|IRoute
|
||||
*/
|
||||
@@ -358,7 +357,7 @@ class SimpleRouter
|
||||
* This type will route the given url to your callback and allow any type of request method
|
||||
*
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param string|array|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouteUrl|IRoute
|
||||
*/
|
||||
@@ -382,7 +381,7 @@ class SimpleRouter
|
||||
* @param array|null $settings
|
||||
* @return RouteController|IRoute
|
||||
*/
|
||||
public static function controller(string $url, $controller, array $settings = null)
|
||||
public static function controller(string $url, string $controller, array $settings = null)
|
||||
{
|
||||
$route = new RouteController($url, $controller);
|
||||
$route = static::addDefaultNamespace($route);
|
||||
@@ -402,7 +401,7 @@ class SimpleRouter
|
||||
* @param array|null $settings
|
||||
* @return RouteResource|IRoute
|
||||
*/
|
||||
public static function resource(string $url, $controller, array $settings = null)
|
||||
public static function resource(string $url, string $controller, array $settings = null)
|
||||
{
|
||||
$route = new RouteResource($url, $controller);
|
||||
$route = static::addDefaultNamespace($route);
|
||||
|
||||
@@ -199,4 +199,15 @@ class RouterRouteTest extends \PHPUnit\Framework\TestCase
|
||||
$this->assertEquals('custom-regex', $output);
|
||||
}
|
||||
|
||||
public function testClassHint()
|
||||
{
|
||||
TestRouter::get('/my/test/url', ['DummyController', 'method1']);
|
||||
TestRouter::all('/my/test/url', ['DummyController', 'method1']);
|
||||
TestRouter::match(['put', 'get', 'post'], '/my/test/url', ['DummyController', 'method1']);
|
||||
|
||||
TestRouter::debug('/my/test/url', 'get');
|
||||
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -78,8 +78,8 @@ class RouterUrlTest extends \PHPUnit\Framework\TestCase
|
||||
public function testSimilarUrls()
|
||||
{
|
||||
// Match normal route on alias
|
||||
TestRouter::resource('/url11', 'DummyController@method1');
|
||||
TestRouter::resource('/url1', 'DummyController@method1', ['as' => 'match']);
|
||||
TestRouter::get('/url11', 'DummyController@method1');
|
||||
TestRouter::resource('/url1', 'ResourceController', ['as' => 'match']);
|
||||
|
||||
TestRouter::debugNoReset('/url1', 'get');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user