How to overwrite request in SLIM 4

Hi,
We are trying to create a custom request to add a single method, but no success in SLIM 4.

In slim 3 we have created a custom response and added in container and all works great.

Any help will be apreciated.

Thanks,
Andrei - doSul Digital

Hi :slight_smile:

Don’t know if I understood you right but…

In Slim 4 if you need to run your app with a custom request you just need to give $app->run() an instance of your Request object. (it can be any Request implementation that follows the PSR-7 standard)

$app->run($request);

If you only need to modify one part of the Request or add something new I think your best option will be to make a PSR-15 Middleware where you manipulate the Request as you wish and add it to the end of your middleware stack so it can run first.

PSR-15 Middlewares receive the Request object as first parameter, you can use it, manipulate it and then add it to the Response Handler received as second parameter, so it can return an adequate Response.

$request = Something that you will do to it;
return $handler->handle($request);

Hope it helps.

I think the $app->run($request); could help us, but I dit not found any example and could not get it running, could you provide an example of how to use our custom request here.
We have a class:

<?php class RequestHandler extends \Slim\Psr7\Request { protected $parsed = null; protected $queryParams = null; public function getParam($paramName, $default = null) ... Thanks

For better help you I need to understand what are you trying to add or modify on the Request.

Can you paste your Slim 3 code here?

We are trying to create a new custom function in REQUEST.
We only have a slim 3 code for response:
Response Class:
<?php
class ResponseHandler extends \Slim\Psr7\Response
{

    private $data;

    public function getData()
    {
        return $this->data;
    }
    public function withData($data)
    {
        $clone = clone $this;
        $clone->data = $data;
        return $clone;
    }
}

In container:
$container->set('response', function ($container) {
    $headers = new \Slim\Http\Headers(['Content-Type' => 'application/json; charset=UTF-8']);
    $response = new ResponseHandler(200, $headers);

    return $response->withProtocolVersion($container->get('settings')['httpVersion']);
});

And we can use it normally:
return $response->withData([
‘id’ => $this->get_id($mdl),
‘message’ => ‘Salvo com sucesso’
]);

Wow finally did it:
Created a request class:
<?php
class RequestHandler extends \Slim\Psr7\Request
{

    protected $parsed = null;
    protected $queryParams = null;
...

And a ServerRequestFactory Class:
<?php

use Slim\Psr7\Cookies;
use Slim\Psr7\Headers;
use Slim\Psr7\Stream;
use Slim\Psr7\UploadedFile;
use Slim\Psr7\Factory\UriFactory;
use Slim\Psr7\Factory\StreamFactory;

class CustomServerRequestFactory extends \Slim\Psr7\Factory\ServerRequestFactory
{

    public static function customCreateFromGlobals(): RequestHandler
    {
        $method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET';
        $uri = (new UriFactory())->createFromGlobals($_SERVER);
        $headers = Headers::createFromGlobals();
        $cookies = Cookies::parseHeader($headers->getHeader('Cookie', []));
        // Cache the php://input stream as it cannot be re-read
        $cacheResource = fopen('php://temp', 'wb+');
        $cache = $cacheResource ? new Stream($cacheResource) : null;
        $body = (new StreamFactory())->createStreamFromFile('php://input', 'r', $cache);
        $uploadedFiles = UploadedFile::createFromGlobals($_SERVER);
        $request = new RequestHandler($method, $uri, $headers, $cookies, $_SERVER, $body, $uploadedFiles);
        $contentTypes = $request->getHeader('Content-Type') ?? [];
        $parsedContentType = '';
        foreach ($contentTypes as $contentType) {
            $fragments = explode(';', $contentType);
            $parsedContentType = current($fragments);
        }
        $contentTypesWithParsedBodies = ['application/x-www-form-urlencoded', 'multipart/form-data'];
        if ($method === 'POST' && in_array($parsedContentType, $contentTypesWithParsedBodies)) {
            return $request->withParsedBody($_POST);
        }
        return $request;
    }
}

And then in our app start:
$request = CustomServerRequestFactory::customCreateFromGlobals();

$app->run($request);

Now our print_r(get_class($request)); gives RequestHandler.
Thank’s for the idea of app run with request.