Skip to main content

Delivering files with PSR-7

This blog post might be outdated!
This blog post was published more than one year ago and might be outdated!
· One min read
Stephan Hochdörfer

When it comes to reading and returning the contents of a file in a PSR-7 middleware most developers seem use code that does the following: Read the file first, then write it to the response body.

public function __invoke(
\Psr\Http\Message\ServerRequestInterface $request,
\Psr\Http\Message\ResponseInterface $response
) {
$filename = '/some/directory/file.txt';
$contents = file_get_contents($filename);

$response->getBody()->rewind();
$response->getBody()->write($contents);
return $response->withStatus(200);
}

This works fine but can simplified quite a bit. Given you use zendframework/zend-diactoros the following code could be an alternative. Since the \Zend\Diactoros\Stream class accepts a string or a resource as constructor parameter, you can pass the file name as is and \Zend\Diactoros\Stream will turn this into a file resource internally.

public function __invoke(
\Psr\Http\Message\ServerRequestInterface $request,
\Psr\Http\Message\ResponseInterface $response
) {
$filename = '/some/directory/file.txt';
$response = $response->withBody(new \Zend\Diactoros\Stream($filename));
return $response->withStatus(200);
}

As you can see there is no need to read from a stream first and then write to the another stream. We do the whole operation in one go - and need less lines of code. A clear win-win for all of us ;)