Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

php

slim

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

like image 620
Mohammad Sharaf Ali Avatar asked Feb 05 '23 20:02

Mohammad Sharaf Ali


2 Answers

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->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 = $next($request, $response);
    $response = $response->withStatus(200)->write(' seq1 ');
    return $response;
});

$mw2 = (function (Request $request, Response $response, callable $next) {
    $response = $next($request, $response);
    $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();

I hope it can help you.

PS: I prefer Slim 3 :D

like image 142
Fefas Avatar answered May 05 '23 21:05

Fefas


You can also get content in this way

Method #1

$streamBody = $response->getBody();
$streamBody->rewind();
$content = $streamBody->getContents();

Method #2

$streamBody = $response->getBody();
$streamBody->rewind();
$content = $streamBody->read($streamBody->getSize());
like image 23
Daniel Abyan Avatar answered May 05 '23 22:05

Daniel Abyan