-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow any callable as a handler #7
Conversation
src/RequestHandler.php
Outdated
if (is_string($requestHandler)) { | ||
$container = $this->container ?: new RequestHandlerContainer(); | ||
$requestHandler = $container->get($requestHandler); | ||
if (is_string($requestHandler) && $this->container->has($requestHandler)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added Container::has()
check because a string can be a callable
.
src/RequestHandler.php
Outdated
} | ||
|
||
if (is_callable($requestHandler)) { | ||
$requestHandler = new CallableHandler($requestHandler); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might as well use existing instanceof
checks for CallableHandler
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Middlewares\Utils\CallableHandler
implements both interfaces (MiddlewareInterface and RequestHandlerInterface) and is callable too (has an __invoke
), so I'd move is_callable()
to the end, in order to avoid a CallableHandler inside other CallableHandler.
Is there an use case for this? The reason why I didn't allow strings as callables is because you never know whether you want a container entry that doesn't exist (so it must throw a notFoundException) or you want a function name. And due the default container can resolve strings, I'd use strings always as container ids and never as callables. And the reason of why only Closure is allowed is because they can be created easily from any callable thanks to Closure::fromCallable, that provide a better control, performance and safety. |
The use case is pretty simple: class FooController
{
public function __invoke(ServerRequestInterface $request) { /* ... */ }
} And the route is defined as:
I would rather not write this for every single route:
|
This is why I added |
The default
Let's say that I have a controller called |
This argument doesn't make sense. By the time this code runs, the container should know what objects it has available and be able to determine that As an aside, many containers are opting to use full class names as the identifier, so it is fairly unlikely that there would be a conflict between |
What I mean is that If strings are considered as callables too, there's no way to restrict the requestHandler is resolved only through the container, so if it exists as a global function it will be executed as a fallback. I can consider accept any callable but strings. Other thing is why you find useful to have a controller with Anyway, your use case should work perfectly right now, because the default RequestHandlerController should handle this case (as it does in the tests), or please, let me know if this is not happening. |
f4cdcca
to
011b3d4
Compare
I don't want to import an interface for all my controllers. There's no benefit to doing that, since the controllers are specific to my application and don't need interop. |
I updated the PR and removed support for callable strings. |
src/RequestHandler.php
Outdated
} | ||
|
||
if (is_callable($requestHandler)) { | ||
$requestHandler = new CallableHandler($requestHandler); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Middlewares\Utils\CallableHandler
implements both interfaces (MiddlewareInterface and RequestHandlerInterface) and is callable too (has an __invoke
), so I'd move is_callable()
to the end, in order to avoid a CallableHandler inside other CallableHandler.
@@ -30,7 +30,7 @@ class RequestHandler implements MiddlewareInterface | |||
*/ | |||
public function __construct(ContainerInterface $container = null) | |||
{ | |||
$this->container = $container; | |||
$this->container = $container ?: new RequestHandlerContainer(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because this is used only inside if (is_string($requestHandler))
, I'd not create the instance in the constructor, but inside that if
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the consistency is valuable. There's no real performance impact of doing this.
Callable handlers, not just closures, should be allowed.
011b3d4
to
2feeebc
Compare
@shadowhand Thanks 😃 |
Callable handlers, not just closures, should be allowed.
Refs #4, #5