The data needs to written to the body of the response object. You can use the built-in Slim Stream
class together with fopen
to to this for you:
$app->get('/test-download', function($request, Slim\Http\Response $response, $args) {
$file = __DIR__ . '/test.html';
$fh = fopen($file, 'rb');
$stream = new \Slim\Http\Stream($fh); // create a stream instance for the response body
return $response->withHeader('Content-Type', 'application/force-download')
->withHeader('Content-Type', 'application/octet-stream')
->withHeader('Content-Type', 'application/download')
->withHeader('Content-Description', 'File Transfer')
->withHeader('Content-Transfer-Encoding', 'binary')
->withHeader('Content-Disposition', 'attachment; filename="' . basename($file) . '"')
->withHeader('Expires', '0')
->withHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->withHeader('Pragma', 'public')
->withBody($stream); // all stream contents will be sent to the response
});
The Content-Length
header will be automatically appended.
The code also worked for me with one Content-Type
header, and without the Content-Transfer-Encoding
header. So you may be able to simplify this by leaving headers out.