Sometimes, there’s a requirement to alter the data in the Response’s body after it has been created by your controller action. For example, we may want to ensure that our brand name is consistently capitalised.

One way to do this is to create middleware that looks like this:

$brandFilter = function ($request, $response, $next) {
    // call next middleware
    $response = $next($request, $response);

    $content = (string)$response->getBody();
    $newContent = str_ireplace('nineteen feet', 'Nineteen Feet', $content);

    $response->getBody()->rewind();
	$response->getBody()->write();

    return $response;
};

This works perfectly, so if my response body contains “I consult thought my company, nineteen feet.“, then the output of the middleware$brandFilter middleware is “I consult thought my company, Nineteen Feet.“, which is exactly what we want.

That’s great, but what happens if the new string is shorter than the old one? For instance, suppose I want to replace all uses of “nineteen feet” with “19FT”.

Using the same middleware, but changing the str_ireplace call with:

$newContent = str_ireplace('nineteen feet', '19FT', $content);

creates this output:

I consult thought my company, 19FT.een feet.

That’s not quite what we wanted! This result is because the new string is shorter, so the characters from the old string are still in the PHP stream and as we haven’t change the length, they are still there. The PSR-7 StreamInterface doesn’t allow us access to the underlying stream, so we can’t call ftruncate on it.

Hence, the easiest solution is to replace the Response’s PSR-7 StreamInterface object with a new one containing what we need:

$brandFilter = function ($request, $response, $next) {
    // call next middleware
    $response = $next($request, $response);

    $content = (string)$response->getBody();
    $newContent = str_ireplace('nineteen feet', '19FT', $content);

    $newBody = new SlimHttpBody(fopen('php://temp', 'r+'));
    $newBody->write($newContent);

    return $response->withBody($newBody);
};

The output is now what we expect:

I consult thought my company, 19FT.

Source: AKRABAT

By Rob