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()
{}
} |
<?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'); |
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);
} |
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);
} |
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);
} |
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()
{}
} |
<?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: