From e86bb59297db20b57b0f57e018cedbab0e2c81db Mon Sep 17 00:00:00 2001 From: fadrian06 Date: Sun, 9 Mar 2025 16:18:28 -0400 Subject: [PATCH] docs: add array{0: class-string, 1: method} to support phpstan level 6 in any project that uses [MyController::class, 'myInstanceMethod'] (phpstan marks that as an invalid callable) --- composer.json | 2 +- flight/Engine.php | 53 +++++++++++++++++++++++++++++-------------- flight/Flight.php | 14 ++++++------ flight/net/Router.php | 34 ++++++++++++++++----------- 4 files changed, 65 insertions(+), 38 deletions(-) diff --git a/composer.json b/composer.json index 23b6b9e..a6a8d63 100644 --- a/composer.json +++ b/composer.json @@ -63,7 +63,7 @@ "test-server": "echo \"Running Test Server\" && php -S localhost:8000 -t tests/server/", "test-server-v2": "echo \"Running Test Server\" && php -S localhost:8000 -t tests/server-v2/", "test-coverage:win": "del clover.xml && phpunit --coverage-html=coverage --coverage-clover=clover.xml && coverage-check clover.xml 100", - "lint": "phpstan --no-progress -cphpstan.neon", + "lint": "phpstan --no-progress --memory-limit=256M -cphpstan.neon", "beautify": "phpcbf --standard=phpcs.xml", "phpcs": "phpcs --standard=phpcs.xml -n", "post-install-cmd": [ diff --git a/flight/Engine.php b/flight/Engine.php index eca1d19..63fd05d 100644 --- a/flight/Engine.php +++ b/flight/Engine.php @@ -34,19 +34,19 @@ * @method EventDispatcher eventDispatcher() Gets event dispatcher * * # Routing - * @method Route route(string $pattern, callable|string $callback, bool $pass_route = false, string $alias = '') + * @method Route route(string $pattern, callable|string|array{0: class-string, 1: string} $callback, bool $pass_route = false, string $alias = '') * Routes a URL to a callback function with all applicable methods - * @method void group(string $pattern, callable $callback, array $group_middlewares = []) + * @method void group(string $pattern, callable $callback, (class-string|callable|array{0: class-string, 1: string})[] $group_middlewares = []) * Groups a set of routes together under a common prefix. - * @method Route post(string $pattern, callable|string $callback, bool $pass_route = false, string $alias = '') + * @method Route post(string $pattern, callable|string|array{0: class-string, 1: string} $callback, bool $pass_route = false, string $alias = '') * Routes a POST URL to a callback function. - * @method Route put(string $pattern, callable|string $callback, bool $pass_route = false, string $alias = '') + * @method Route put(string $pattern, callable|string|array{0: class-string, 1: string} $callback, bool $pass_route = false, string $alias = '') * Routes a PUT URL to a callback function. - * @method Route patch(string $pattern, callable|string $callback, bool $pass_route = false, string $alias = '') + * @method Route patch(string $pattern, callable|string|array{0: class-string, 1: string} $callback, bool $pass_route = false, string $alias = '') * Routes a PATCH URL to a callback function. - * @method Route delete(string $pattern, callable|string $callback, bool $pass_route = false, string $alias = '') + * @method Route delete(string $pattern, callable|string|array{0: class-string, 1: string} $callback, bool $pass_route = false, string $alias = '') * Routes a DELETE URL to a callback function. - * @method void resource(string $pattern, string $controllerClass, array> $methods = []) + * @method void resource(string $pattern, class-string $controllerClass, array> $methods = []) * Adds standardized RESTful routes for a controller. * @method Router router() Gets router * @method string getUrl(string $alias) Gets a url from an alias @@ -85,10 +85,29 @@ class Engine * @var array List of methods that can be extended in the Engine class. */ private const MAPPABLE_METHODS = [ - 'start', 'stop', 'route', 'halt', 'error', 'notFound', - 'render', 'redirect', 'etag', 'lastModified', 'json', 'jsonHalt', 'jsonp', - 'post', 'put', 'patch', 'delete', 'group', 'getUrl', 'download', 'resource', - 'onEvent', 'triggerEvent' + 'start', + 'stop', + 'route', + 'halt', + 'error', + 'notFound', + 'render', + 'redirect', + 'etag', + 'lastModified', + 'json', + 'jsonHalt', + 'jsonp', + 'post', + 'put', + 'patch', + 'delete', + 'group', + 'getUrl', + 'download', + 'resource', + 'onEvent', + 'triggerEvent' ]; /** @var array Stored variables. */ @@ -425,26 +444,26 @@ protected function processMiddleware(Route $route, string $eventName): bool if ($eventName === Dispatcher::FILTER_BEFORE && is_object($middleware) === true && ($middleware instanceof Closure)) { $middlewareObject = $middleware; - // If the object has already been created, we can just use it if the event name exists. + // If the object has already been created, we can just use it if the event name exists. } elseif (is_object($middleware) === true) { - $middlewareObject = method_exists($middleware, $eventName) === true ? [ $middleware, $eventName ] : false; + $middlewareObject = method_exists($middleware, $eventName) === true ? [$middleware, $eventName] : false; - // If the middleware is a string, we need to create the object and then call the event. + // If the middleware is a string, we need to create the object and then call the event. } elseif (is_string($middleware) === true && method_exists($middleware, $eventName) === true) { $resolvedClass = null; // if there's a container assigned, we should use it to create the object if ($this->dispatcher->mustUseContainer($middleware) === true) { $resolvedClass = $this->dispatcher->resolveContainerClass($middleware, $params); - // otherwise just assume it's a plain jane class, so inject the engine - // just like in Dispatcher::invokeCallable() + // otherwise just assume it's a plain jane class, so inject the engine + // just like in Dispatcher::invokeCallable() } elseif (class_exists($middleware) === true) { $resolvedClass = new $middleware($this); } // If something was resolved, create an array callable that will be passed in later. if ($resolvedClass !== null) { - $middlewareObject = [ $resolvedClass, $eventName ]; + $middlewareObject = [$resolvedClass, $eventName]; } } diff --git a/flight/Flight.php b/flight/Flight.php index 7e43877..064bd16 100644 --- a/flight/Flight.php +++ b/flight/Flight.php @@ -34,19 +34,19 @@ * @method EventDispatcher eventDispatcher() Gets event dispatcher * * # Routing - * @method static Route route(string $pattern, callable|string $callback, bool $pass_route = false, string $alias = '') + * @method static Route route(string $pattern, callable|string|array{0: class-string, 1: string} $callback, bool $pass_route = false, string $alias = '') * Maps a URL pattern to a callback with all applicable methods. - * @method static void group(string $pattern, callable $callback, callable[] $group_middlewares = []) + * @method static void group(string $pattern, callable $callback, (class-string|callable|array{0: class-string, 1: string})[] $group_middlewares = []) * Groups a set of routes together under a common prefix. - * @method static Route post(string $pattern, callable|string $callback, bool $pass_route = false, string $alias = '') + * @method static Route post(string $pattern, callable|string|array{0: class-string, 1: string} $callback, bool $pass_route = false, string $alias = '') * Routes a POST URL to a callback function. - * @method static Route put(string $pattern, callable|string $callback, bool $pass_route = false, string $alias = '') + * @method static Route put(string $pattern, callable|string|array{0: class-string, 1: string} $callback, bool $pass_route = false, string $alias = '') * Routes a PUT URL to a callback function. - * @method static Route patch(string $pattern, callable|string $callback, bool $pass_route = false, string $alias = '') + * @method static Route patch(string $pattern, callable|string|array{0: class-string, 1: string} $callback, bool $pass_route = false, string $alias = '') * Routes a PATCH URL to a callback function. - * @method static Route delete(string $pattern, callable|string $callback, bool $pass_route = false, string $alias = '') + * @method static Route delete(string $pattern, callable|string|array{0: class-string, 1: string} $callback, bool $pass_route = false, string $alias = '') * Routes a DELETE URL to a callback function. - * @method static void resource(string $pattern, string $controllerClass, array> $methods = []) + * @method static void resource(string $pattern, class-string $controllerClass, array> $methods = []) * Adds standardized RESTful routes for a controller. * @method static Router router() Returns Router instance. * @method static string getUrl(string $alias, array $params = []) Gets a url from an alias diff --git a/flight/net/Router.php b/flight/net/Router.php index 8025024..455fdb4 100644 --- a/flight/net/Router.php +++ b/flight/net/Router.php @@ -56,12 +56,20 @@ class Router * * @var array */ - protected array $allowedMethods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']; + protected array $allowedMethods = [ + 'GET', + 'POST', + 'PUT', + 'PATCH', + 'DELETE', + 'HEAD', + 'OPTIONS' + ]; /** * Gets mapped routes. * - * @return array Array of routes + * @return array Array of routes */ public function getRoutes(): array { @@ -80,7 +88,7 @@ public function clear(): void * Maps a URL pattern to a callback function. * * @param string $pattern URL pattern to match. - * @param callable|string $callback Callback function or string class->method + * @param callable|string|array{0: class-string, 1: string} $callback Callback function or string `class->method` * @param bool $pass_route Pass the matching route object to the callback. * @param string $route_alias Alias for the route. */ @@ -133,7 +141,7 @@ public function map(string $pattern, $callback, bool $pass_route = false, string * Creates a GET based route * * @param string $pattern URL pattern to match - * @param callable|string $callback Callback function or string class->method + * @param callable|string|array{0: class-string, 1: string} $callback Callback function or string `class->method` * @param bool $pass_route Pass the matching route object to the callback * @param string $alias Alias for the route */ @@ -146,7 +154,7 @@ public function get(string $pattern, $callback, bool $pass_route = false, string * Creates a POST based route * * @param string $pattern URL pattern to match - * @param callable|string $callback Callback function or string class->method + * @param callable|string|array{0: class-string, 1: string} $callback Callback function or string `class->method` * @param bool $pass_route Pass the matching route object to the callback * @param string $alias Alias for the route */ @@ -159,7 +167,7 @@ public function post(string $pattern, $callback, bool $pass_route = false, strin * Creates a PUT based route * * @param string $pattern URL pattern to match - * @param callable|string $callback Callback function or string class->method + * @param callable|string|array{0: class-string, 1: string} $callback Callback function or string `class->method` * @param bool $pass_route Pass the matching route object to the callback * @param string $alias Alias for the route */ @@ -172,7 +180,7 @@ public function put(string $pattern, $callback, bool $pass_route = false, string * Creates a PATCH based route * * @param string $pattern URL pattern to match - * @param callable|string $callback Callback function or string class->method + * @param callable|string|array{0: class-string, 1: string} $callback Callback function or string `class->method` * @param bool $pass_route Pass the matching route object to the callback * @param string $alias Alias for the route */ @@ -185,7 +193,7 @@ public function patch(string $pattern, $callback, bool $pass_route = false, stri * Creates a DELETE based route * * @param string $pattern URL pattern to match - * @param callable|string $callback Callback function or string class->method + * @param callable|string|array{0: class-string, 1: string} $callback Callback function or string `class->method` * @param bool $pass_route Pass the matching route object to the callback * @param string $alias Alias for the route */ @@ -199,7 +207,7 @@ public function delete(string $pattern, $callback, bool $pass_route = false, str * * @param string $groupPrefix group URL prefix (such as /api/v1) * @param callable $callback The necessary calling that holds the Router class - * @param array $groupMiddlewares + * @param (class-string|callable|array{0: class-string, 1: string})[] $groupMiddlewares * The middlewares to be applied to the group. Example: `[$middleware1, $middleware2]` */ public function group(string $groupPrefix, callable $callback, array $groupMiddlewares = []): void @@ -226,7 +234,7 @@ public function route(Request $request) if ($urlMatches === true && $methodMatches === true) { $this->executedRoute = $route; return $route; - // capture the route but don't execute it. We'll use this in Engine->start() to throw a 405 + // capture the route but don't execute it. We'll use this in Engine->start() to throw a 405 } elseif ($urlMatches === true && $methodMatches === false) { $this->executedRoute = $route; } @@ -240,7 +248,7 @@ public function route(Request $request) * Gets the URL for a given route alias * * @param string $alias the alias to match - * @param array $params the parameters to pass to the route + * @param array $params the parameters to pass to the route */ public function getUrlByAlias(string $alias, array $params = []): string { @@ -311,7 +319,7 @@ public function mapResource( return in_array($key, $only, true) === true; }, ARRAY_FILTER_USE_KEY); - // Exclude these controller methods + // Exclude these controller methods } elseif (isset($options['except']) === true) { $except = $options['except']; $defaultMapping = array_filter($defaultMapping, function ($key) use ($except) { @@ -331,7 +339,7 @@ function (Router $router) use ($controllerClass, $defaultMapping, $aliasBase): v foreach ($defaultMapping as $controllerMethod => $methodPattern) { $router->map( $methodPattern, - [ $controllerClass, $controllerMethod ] + [$controllerClass, $controllerMethod] )->setAlias($aliasBase . '.' . $controllerMethod); } },