Download a File
The title may sound unclear enough, but the task is simple. You’ve to make a file download process within a Zend Framework’s controller. Let’s assume we’ve the DownloadController setup:
<?php class DownloadController extends Zend_Controller_Action { public function indexAction() {} } |
In PHP there are at least three simple lines of code that will do the job of downloading a file.
header('Content-Type: image/jpeg'); header('Content-Disposition: attachment; filename="logo.jpg"'); readfile('images/logo.jpg'); |
Note that here there is a content-type header, which is important cause the browsers understands what kind of file is supposed to be downloaded. The second line suggests a name of the downloaded file and the third one returns the file to the client.
Download a File … within Zend Framework
Those three lines wont work alone in a ZF application, because there’s no view, but even if you create a .phtml (view) file for this action it won’t work, because the header of the returned file is modified.
The question is how to possibly return the file for download, perhaps write some statistics to the database and if there’s a problem (some permission issues for instance) return a message to the user.
The Basic Solution
The solution is simple. First make it work by disabling the view and possibly the layout for this action:
public function indexAction() { header('Content-Type: image/jpeg'); header('Content-Disposition: attachment; filename="logo.jpg"'); readfile('images/logo.jpg'); // disable the view ... and perhaps the layout $this->view->layout()->disableLayout(); $this->_helper->viewRenderer->setNoRender(true); } |
Than add some code where you can check the permissions. Just because there’s no view for this action you can redirect to another – errorAction():
public function indexAction() { if (userHasNoPermissions) { $this->view->msg = 'This file cannot be downloaded!'; $this->_forward('error', 'download'); } header('Content-Type: image/jpeg'); header('Content-Disposition: attachment; filename="logo.jpg"'); readfile('images/logo.jpg'); // disable layout and view $this->view->layout()->disableLayout(); $this->_helper->viewRenderer->setNoRender(true); } |
But that still will prompt you a file to download, so there should be a return statement that will return false:
public function indexAction() { if (userHasNoPermissions) { $this->view->msg = 'This file cannot be downloaded!'; $this->_forward('error', 'download'); return FALSE; } header('Content-Type: image/jpeg'); header('Content-Disposition: attachment; filename="logo.jpg"'); readfile('images/logo.jpg'); // disable layout and view $this->view->layout()->disableLayout(); $this->_helper->viewRenderer->setNoRender(true); } |
So here’s the complete source of DownloadController.php:
<?php class DownloadController extends Zend_Controller_Action { public function indexAction() { if (userHasNoPermissions) { $this->view->msg = 'This file cannot be downloaded!'; $this->_forward('error', 'download'); return FALSE; } header('Content-Type: image/jpeg'); header('Content-Disposition: attachment; filename="logo.jpg"'); readfile('images/logo.jpg'); // disable layout and view $this->view->layout()->disableLayout(); $this->_helper->viewRenderer->setNoRender(true); } public function errorAction() {} } |
and the error.phtml:
<?php echo $this->msg ?> |
Related posts:
- Setting Up Global Cache in Zend Framework
- Models in Zend Framework – Initialize All Methods with init()
- Upload a File with Zend Framework
- Download Images with PHP
- Bind Zend Action with Non-Default View – Part 2

Great script, but I do I use it ?
And does it work in IE ?
Yeah, great script.
Perhabs you would add a automatic mime-type-detection?
Regards Jan
I was wondering if I had to create a controller for that.
Thanks for clearing that up…
Good walk through.
@Jan there’s a little bug, should be:
header(‘Content-Type: ‘. $mtype);