Mohammad Sharaf Ali
Mohammad Sharaf Ali

Reputation: 579

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:

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

Upvotes: 5

Views: 7023

Answers (3)

Fefas
Fefas

Reputation: 165

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

Upvotes: 7

The Billionaire Guy
The Billionaire Guy

Reputation: 3552

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

i had the same issue and couldn't just figure out why am getting empty body response, so i ended up adding json_encode($my_value) to my return variable and that was the magic. Now i can proceed with buying a new dog and probably getting married. Hope this helps someone.

/**
 * method - GET
 */
$app->get('/posts[/]', function ($request, $response, $args) {
    $db = new DbHandler();
    // fetching all
    $result = $db->getAllPosts();
    return json_encode($result);
});

And on the other side

/**
 * GetPosts
 */
public function getAllPosts() {
    // Instantiate DBH
    // make a connection to mysql here
    $db = new PDO_Wrapper();
    $db->query("SELECT * FROM all_posts WHERE post_status = :Publish AND post_type = :Post ORDER BY post_date DESC");
    $binding_array = array(":Publish" => "publish", ":Post" => "post");
    $db->bindArray($binding_array);
    $results = $db->resultset();
    return $results;
}

Upvotes: 0

Daniel Abyan
Daniel Abyan

Reputation: 321

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());

Upvotes: 2

Related Questions