File downloads with Zend Diactoros

PSR-7 compatible Response class for file downloads

Posted by on September 01, 2016 File downloads with Zend Diactoros

In my daily work I often need the possibility of file downloads. I basically use PSR-7 standard and Zend Diactoros for HTTP communication. Zend Diactoros does not have a built in support for file downloads. Therefore I wrote a response which is supporting file downloads. Here it is:

<?php

use Psr\Http\Message\StreamInterface;
use Zend\Diactoros\Response;
use Zend\Diactoros\Response\InjectContentTypeTrait;
use Zend\Diactoros\Stream;

class AttachmentResponse extends Response
{
    use InjectContentTypeTrait;

    /**
     * Create a file attachment response.
     *
     * Produces a text response with a Content-Type of given file mime type and a default
     * status of 200.
     *
     * @param string $file Valid file path
     * @param int $status Integer status code for the response; 200 by default.
     * @param array $headers Array of headers to use at initialization.
     * @internal param StreamInterface|string $text String or stream for the message body.
     */
    public function __construct($file, $status = 200, array $headers = [])
    {
        $fileInfo = new \SplFileInfo($file);

        $headers = array_replace($headers, [
            'content-length' => $fileInfo->getSize(),
            'content-disposition' => sprintf('attachment; filename=%s', $fileInfo->getFilename()),
        ]);

        parent::__construct(
            new Stream($fileInfo->getRealPath(), 'r'),
            $status,
            $this->injectContentType((new \finfo(FILEINFO_MIME_TYPE))->file($fileInfo->getRealPath()), $headers)
        );
    }
}