However when I do so, I’m getting the following error:
Using $this when not in object context in....
The route works ok if I use the ‘classname:method’ style.
Is it really possible to do it that way? Wouldn’t the first field of the array callback need to be an object instead of a class name to be considered a valid php callback?
<?php
namespace App\Action;
use Psr\Http\Message\ResponseInterface;
use Slim\Http\Request;
use Slim\Http\Response;
class HomeIndexAction
{
public function __invoke(Request $request, Response $response): ResponseInterface
{
return $response->write("Hello world");
}
}
Maybe the problem is that the [‘className’, ‘method’] it is a valid callable but it is not a instance of Closure, therefore it can not be bound to the scope of the container, and $this won’t be usable. It will work for static methods or methods that not refer to $this though.
But, that would mean that the syntax in Glenn Eggleton’s blog is not valid in Slim. In Slim docs doesn’t seem to be documented that style either. I am confused.
My suggested route is document in the Slim docs here:
Note that the second parameter is a callback. You could specify a Class (which need a __invoke() implementation) instead of a Closure. You can then do the mapping somewhere else:
The positive effect with the ::class syntax is, your IDE (and phpstan) can type hint this class and you can refactor this class very easily. Last but not least, your Controller (or Action) class is responsible for only one thing (SRP).
Hi @odan, thank you for your help! I like the idea of Action classes to meet the SRP, however…
What would be the best way to deal with the Action classes, should I put each of them in their own file so they can be loaded with psr-4 autoloader? What if there are a lot of actions? Isn’t it difficult to deal with so many files?
Also, where will you set up the services needed by the Action class? In the constructor, or adding the Action Class to the container?
I think that setting up the services for the controllers, either in the constructor (and receiving the entire container), or adding the entire class to the container itself it’s pretty much the same task over and over. Is this ok? I didn’t use a framework before, so I am a little confused with these things.