Compressing text - gzip?

I have a few ajax requests that return some big loads and I’d like to compress the data. Does anyone have any idea how to do this using Slim 3? I’ve found some methods, but they’re 3-4 years old.

Any help would be appreciated

Hi @twigz What have you tried so far?

To compress the response it would be possible to use a middleware like this:

// Gzip compression middleware
$app->add(function (Request $request, Response $response, $next) {
    if ($request->hasHeader('Accept-Encoding') &&
        stristr($request->getHeaderLine('Accept-Encoding'), 'gzip') === false
    ) {
        // Browser doesn't accept gzip compression
        return $next($request, $response);
    }

    /** @var Response $response */
    $response = $next($request, $response);

    if ($response->hasHeader('Content-Encoding')) {
        return $next($request, $response);
    }

    // Compress response data
    $deflateContext = deflate_init(ZLIB_ENCODING_GZIP);
    $compressed = deflate_add($deflateContext, (string)$response->getBody(), \ZLIB_FINISH);

    $stream = fopen('php://memory', 'r+');
    fwrite($stream, $compressed);
    rewind($stream);

    return $response
        ->withHeader('Content-Encoding', 'gzip')
        ->withHeader('Content-Length', strlen($compressed))
        ->withBody(new \Slim\Http\Stream($stream));
});

@odan, thanks for the prompt response. This is a good solution, but I managed to gzip all text responses through apache.

Although I’m not sure this is the best solution.

Oden’s approach is correct, Slim uses a middleware architecture, this behavior allows you to use a text gzip functionality through your app.

For those who want this to work in Slim 4, some small adjustments are needed:

$app->add(function (Request $request, RequestHandler $handler) {

    if ($request->hasHeader('Accept-Encoding') &&
        stristr($request->getHeaderLine('Accept-Encoding'), 'gzip') === false
    ) {
        // Browser doesn't accept gzip compression
        return $handler->handle($request);
    }

    /** @var Response $response */
    $response = $handler->handle($request);

    if ($response->hasHeader('Content-Encoding')) {
        return $handler->handle($request);
    }

    // Compress response data
    $deflateContext = deflate_init(ZLIB_ENCODING_GZIP);
    $compressed = deflate_add($deflateContext, (string)$response->getBody(), \ZLIB_FINISH);

    $stream = fopen('php://memory', 'r+');
    fwrite($stream, $compressed);
    rewind($stream);

    return $response
        ->withHeader('Content-Encoding', 'gzip')
        ->withHeader('Content-Length', strlen($compressed))
        ->withBody(new \Slim\Psr7\Stream($stream));
});

Note I am using Slim Psr7, the Stream wrapper may be different if you’re using something else…
I’m also not certain how efficient it is to buffer the entire request, then compress it, and then stream it out again, but it technically works so… :man_shrugging:

1 Like