Filter response with Middleware

Hello,

I’ve got a class with optional properties, when using json_encode, these are encoded as ‘null’ when they have no value in the object.
I figured that with Middleware I could filter out the null values.
However i can’t seem to retrieve the raw JSON data of my body.
This is my code so far:

$app->add(function ($request, $response, $next) {
	$response = $next($request, $response);

	if($response->getHeaderLine('Content-type') == 'application/json;charset=utf-8'){
		$content =$response->getBody();
		$response->getBody()->rewind();
		$response->getBody()->write(preg_replace('/,\s*"[^"]+":null|"[^"]+":null,?/', '', $content));

		return $response;
	}

	return $response;
});

It seems the getBody() call returns more than just the body: {actual body} [] {“uid”:“acf9546”}

Is there a way to apply this filter?

There are two things going on here.

Firstly, $content is an instance of Slim\Http\Stream and so the you use it within the preg_replace(), it will call __toString() resulting in a rewind followed by a play of the stream. Hence your filter appends to the end of the current data.

To fix this:

    $content = (string)$response->getBody();

The second issue is that when you write to the stream having rewound, the length of data in the stream is the same as it was before. i.e. you will have rogue data at the end.

To fix this you need to replace the Response’s body with your own. Hence your filter needs to look like this:

$app->add(function ($request, $response, $next) {
    $response = $next($request, $response);

    if ($response->getHeaderLine('Content-type') == 'application/json;charset=utf-8') {
        $content = (string)$response->getBody();
        $newBody = new \Slim\Http\Body(fopen('php://temp', 'r+'));
        $newBody->write(preg_replace('/,\s*"[^"]+":null|"[^"]+":null,?/', '', $content));
        $response = $response->withBody($newBody);
    }

    return $response;
});

My hat’s off to you, that works :slight_smile:

Maybe this is something to add in the User Guide.