Monday, February 25, 2013

Sending stream responses with Zend Framework 2, Part 1

Sending stream responses is a new feature in Zend Framework 2.1. This short introduction will help you getting startet on how to send stream responses in Zend Framework 2.
Most times an application would deliver file downloads or video streaming with static assets, delivered directly frm Apache or Nginx. But sometimes there are restrictions: Only logged-in users should be able to download this file, watch this content, perhabs even a more complicated permission system. Then the application needs to do some permission checks and stream the response.
In this example we assume a simple file download, we deliver the file as stream response, because this is much less memory consuming and more efficient, compared to grabbing the file content and pushing it to the response body of the default response object.

namespace Application\Controller;

use Zend\Http\Headers;
use Zend\Http\Response\Stream;
use Zend\Mvc\Controller\AbstractActionController;

class IndexController extends AbstractActionController
{
    public function fileAction()
    {
        $file = '/path/to/my/file.txt';
        
        $response = new Stream();
        $response->setStream(fopen($file, 'r'));
        $response->setStatusCode(200);
        $response->setStreamName(basename($file));

        $headers = new Headers();
        $headers->addHeaders(array(
            'Content-Disposition' => 'attachment; filename="' . basename($file) .'"',
            'Content-Type' => 'application/octet-stream',
            'Content-Length' => filesize($file)
        ));
        $response->setHeaders($headers);
        return $response;
    }
}

Even more complex use cases with download resume and speed limits are also possible in the future, but this is part of my next blog post about this topic. However you can see how easy it is to send stream responses with Zend Framework 2. As we return the response object directly in the controller, no view is created and rendered, too, so this is really a very fast operation.

11 comments:

  1. Hi

    Where is the best place (folder) to put a text file?

    Thanks

    ReplyDelete
  2. I would suggest two places:
    1) my-app/data/**, if this file belongs to the application
    2) my-app/module/my-module/data/**, if this file belongs to a module

    ReplyDelete
  3. hi, want to connect to remote server write log or .txt file at remote place in append mode

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete
  5. I want to write data into a file using zf2..any help appreciated.

    ReplyDelete
    Replies
    1. This has nothing to do with zf2. You can do this with pure php. Like php -r "file_put_contents('c', 'foo');" && cat c

      Delete
  6. I did not know about this feature: it seems easy and very useful e.g. with videos or other big files. I'm surely going to read about it: thanks for sharing!

    ReplyDelete
  7. All request redirected to indez.php.So how can i put file on my wedsite..tks

    ReplyDelete
  8. how download or red blob file from database

    ReplyDelete
    Replies
    1. This depends on your used database. With PostgreSQL or MongoDB you can get the db field, and this will be a resource. The resource can be used to `passthrough`. With MySQL there is currently no solution within PHP, as the whole blob is read into memory at once.

      Delete