Search code examples
phpslim

How to modify slim v3 response body before and after route execution?


I'm unable to get response body in slim v3 and its always blank. My code is:

<?php

use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
use \Slim\App as Slim;

require 'vendor/autoload.php';

$config['determineRouteBeforeAppMiddleware'] = true;

$app = new Slim(['settings' => $config]);

$mw = (function (Request $request, Response $response, callable $next) {
    $response = $response->withStatus(200)->write(' before ');
    $response = $next($request, $response);
    $body = $response->getBody()->getContents();
    $response = $response->withJson(array('data' => $body)); // output should be {"data":" Hello, User  seq1  seq2 "}
    return $response;
});

$mw1 = (function (Request $request, Response $response, callable $next) {
    $response = $next($request, $response);
    $response = $response->withStatus(200)->write(' seq1 ');
    return $response;
});

$mw2 = (function (Request $request, Response $response, callable $next) {
    $response = $next($request, $response);
    $response->withStatus(200)->write(' seq2 ');
    return $response;

});

$app->add($mw);

$app->get('/hello/{name}', function (Request $request, Response $response) {
    $name = $request->getAttribute('name');
    $response->getBody()->write(" Hello, $name ");
    return $response;
})->add($mw1)->add($mw2);

$app->run();

What I want to do is the following:

  • I don't want to add withJson() at the end of each route just to encode my json and output to client (browser). I want the middleware to handle this for me after (any) route execution ends.
  • I want to get the final body and assign it to an array like $data['data'] = $body and than json encode it and return the modified response.

P.S. Slim v2 was much easier than Slim v3


Solution

  • Try to change getContents() for __toString() at the middleware mw. Another change that should be done is on mw2: you have to return the new response created.

    Look the complete code:

    <?php
    
    use \Psr\Http\Message\ServerRequestInterface as Request;
    use \Psr\Http\Message\ResponseInterface as Response;
    use \Slim\App as Slim;
    
    require 'vendor/autoload.php';
    
    $config['determineRouteBeforeAppMiddleware'] = true;
    
    $app = new Slim(['settings' => $config]);
    
    $mw = (function (Request $request, Response $response, callable $next): Response {
        $response = $response->withStatus(200)->write(' before ');
        $response = $next($request, $response);
        $body = $response->getBody()->__toString();
        $response = $response->withJson(array('data' => $body)); // output should be {"data":" Hello, User  seq1  seq2 "}
        return $response;
    });
    
    $mw1 = (function (Request $request, Response $response, callable $next): Response {
        $response = $next($request, $response);
        $response = $response->withStatus(200)->write(' seq1 ');
        return $response;
    });
    
    $mw2 = (function (Request $request, Response $response, callable $next): Response {
        $response = $next($request, $response);
        $response = $response->withStatus(200)->write(' seq2 ');
        return $response;
    });
    
    $app->add($mw);
    
    $app->get('/hello/{name}', function (Request $request, Response $response): Response {
        $name = $request->getAttribute('name');
        $response->getBody()->write(" Hello, $name ");
        return $response;
    })->add($mw1)->add($mw2);
    
    $app->run();
    

    I hope it can help you.

    PS: I prefer Slim 3 :D