I've set up a new app based on the SlimPHP team's Slim Skeleton application. Inside of my route definitions, I want to be able to access the route parser as described in the Slim4 documentation. So, for example, I'd like to be able to edit the skeleton's app/routes.php file something like this:
$app->get('/', function (Request $request, Response $response) {
$routeParser = $app->getRouteCollector()->getRouteParser(); // this doesn't work
$response->getBody()->write('Hello world! ' . $routeParser->urlFor('something'));
return $response;
});
It makes sense that $app->getRouteCollector()->getRouteParser()
doesn't work, because $app
isn't defined here. But I would think that we'd instead call $this->getRouteCollector()->getRouteParser();
, but that gives the error: "Call to undefined method DI\\Container::getRouteCollector()"
.
It definitely seems that my confusion is about Dependency Injection, which is new for me and not coming naturally to me. I'd honestly love to define the $routeParser variable somewhere else (inside index.php?) so that I could access it in any route definition without having to call $app->getRouteCollector()->getRouteParser() every time. But at the moment I'd settle for anything that worked.
Slim skeleton actually demonstrate an example of what you need to achieve. After creating the App instance in index.php, there is an assignment like this:
// Instantiate the app
AppFactory::setContainer($container);
$app = AppFactory::create();
$callableResolver = $app->getCallableResolver();
You can do the same:
$routeParser = $app->getRouteCollector()->getRouteParser();
And if you really need this instance of RouteParser to be available inside every route callback, you can put it in dependency container, something like:
$container->set(Slim\Interfaces\RouteParserInterface::class, $routeParser);
Then you can use PHP-DI auto-wiring feature to inject this RouteParser into controller constructor:
use Slim\Interfaces\RouteParserInterface;
class SampleController {
public function __construct(RouteParserInterface $routeParser) {
$this->routeParser = $routeParser;
//...
}
}
or if you need to call $container->get()
inside any of your route callbacks:
$app->get('/', function (Request $request, Response $response) {
$routeParser = $this->get(Slim\Interfaces\RouteParserInterface::class);
$response->getBody()->write('Hello world! ' . $routeParser->urlFor('something'));
return $response;
});