Accessing request outside of route

I’m still confused by the structure of Slim 4 and its decoupling of everything.

The upgrade guide says:

Changes to Container

Slim no longer has a Container so you need to supply your own. If you were relying on request or response being in the container, then you need to either set them to a container yourself, or refactor. Also, App::__call() method has been removed, so accessing a container property via $app->key_name() no longer works.

I need to access the request (specifically, the POST data) within the context of a class’s method.

In Slim 2, I could do:

global $app;
$req = $app->request();

In Slim 3, I could do:

global $app;
$request = $app->getContainer()->get('request')

What’s the Slim 4 way to access it?

FYI, I’m creating my container like so:

$container = new \DI\Container();
AppFactory::setContainer($container);
$app = AppFactory::create();
$container = $app->getContainer();

Thanks for the insight.

The request and response objects are context-specific and do not belong in the container.
For this reason, these objects were removed from the container in Slim 4.

I can appreciate that, but then how do you access the request when you need it inside of a class?

The question is what kind of class? A controller, single action controller class or a middleware class?

A user model (specifically class User extends \RedBeanPHP\SimpleModel, in its own namespace Model.) It has a method that checks the POST data to see if its correct and generates flash messages when it’s not.

But a model is another layer in MVC and should handly only the business logic and data access logic and not the http specific tasks. Only a controller or a middleware is responsible for the http request / response specific tasks. You could pass the data (but not the request object) from the controller to your model instead. Then your model (layer) is decoupled from the controller (layer) and better testable.

Hi guys!

I think in Slim 4 you can make something like this, to get the request object.

    $container = new \DI\Container();
    AppFactory::setContainer($container);
    $app = AppFactory::create();
    $container = $app->getContainer();

    ...
    ...
    ...

    // Post Endpoint Example
    $app->post('/hi', function ($request, $response, array $args) {
        $input = $request->getParsedBody();
        $response->getBody()->write(json_encode($input));

        return $response->withHeader('Content-Type', 'application/json')->withStatus(200);
    });

So the first param is the $request object.
Then, for example you can get the request data with: $request->getParsedBody();
Lastly, you could pass the $input to check the POST data to your model etc, etc.