Во-первых можно просто послать заголовки
$file = 'path/to/file'; header("X-Sendfile: $file"); header("Content-type: application/octet-stream"); header('Content-Disposition: attachment; filename="' . basename($file) . '"');Во-вторых для Zend Framework нашел такой хелпер контроллера
/** * X-Sendfile controller helper * * @copyright Copyright (c) 2008-2009 Pro Soft Resources USA Inc. * (http://www.prosoftpeople.com) * @author Rolando Espinoza La fuente (rho@prosoftpeople.com) * @license http://www.opensource.org/licenses/bsd-license.php * New BSD License * @version $Id$ */ class Zend_Controller_Action_Helper_Xsendfile extends Zend_Controller_Action_Helper_Abstract { /** * @var bool Use Nginx specific header */ protected $_isNginx = false; /** * @var bool Wheter to force download. Default true. */ protected $_forceDownload = true; /** * Send files through X-Sendfile feature * * @param string $path File path. * @param string $filename File name. Optional. * @return $this */ public function xsendfile($path, $mime = null, $filename = null) { // set filename if not given if (null === $filename) { $filename = basename($path); } $response = $this->getResponse(); // send mime info if (null !== $mime) { $response->setHeader('Content-Type', $mime); } // send file as attachment if ($this->forceDownload()) { $contentDisposition = 'attachment; filename=' . $filename; } else { $contentDisposition = 'inline; filename=' . $filename; } // if server is Nginx use different header if ($this->isNginx()) { $headerName = 'X-Accel-Redirect'; } else { $headerName = 'X-Sendfile'; } // set response headers $response->setHeader('Content-Disposition', $contentDisposition) ->setHeader($headerName, $path); // Done. Webserver will send the file return $this; } /** * Force download flag * * @param boolean Optional. * @return boolean */ public function forceDownload($flag = null) { if ($flag !== null) { $this->_forceDownload = (bool) $flag; } return $this->_forceDownload; } /** * Nginx web server flag * * TODO: Support internal paths * * @param boolean Optional. * @return boolean */ public function isNginx($flag = null) { if ($flag !== null) { $this->_isNginx = (bool) $flag; } return $this->_isNginx; } /** * Direct pattern * * @param string $path File path. * @param string $filename File name. Optional. * @return $this */ public function direct($path, $mime = null, $filename = null) { return $this->xsendfile($path, $mime, $filename); } }Пример использования в контроллере
public function downloadAction() { // disable output $this->_helper->layout->disableLayout(); $this->_helper->viewRenderer->setNoRender(TRUE); $fileId = $this->_request->getParam('fid'); $fileObj = $this->_helper->doctrineEntityManager ->getRepository('File') ->findOneBy(array('id' => $fileId)); // Проверяем права на скачивание файла if ($this->user->getStatus() === 'free') { if ($fileObj->getStatus() === 'pro') die('Permission denied'); } // if using nginx //$this->_helper->Xsendfile->isNginx(true); // not force download //$this->_helper->Xsendfile->forceDownload(false); // send file with custom name //$this->_helper->xsendfile($file, 'application/pdf', 'report.pdf'); $this->_helper->xsendfile($fileObj->getFilePath(), $fileObj->getFileMime()); }Для того чтобы все это работало должен быть установлен модуль apache XSendfile (иначе будете скачивать файлы весом 0 байт):
root@host:~# apt-cache search xsendfile libapache2-mod-xsendfile - Serve large static files efficiently from web applications root@host:~# apt-get install libapache2-mod-xsendfileПосле того как модуль установлен, проверяем его наличие в разрешенных модулях apache
root@host:~# ls /etc/apache2/mods-enabled/
...
xsendfile.load
...
И если его там нет создаем ссылку на загрузчик модуля в /etc/apache2/mods-avaliable.
И в debian squeeze и в ubuntu 12.04 он прописался там после установки.
Далее нам нужно включить модуль в .htaccess нашего сайта.
Тут для debian и ubuntu есть различия, все дело в разных версиях модуля в репозиториях.
Для Ubuntu .htaccess:
... # enable xsendfile XSendFile On ...А в конфигурации хоста надо добавить следующую директиву, она разрешает загружать файлы из указанной директории, которая находится за пределами корня веб-сервера (корень /var/www/mysite/public)
leon@Berta:~$ cat /etc/apache2/sites-enabled/mysite.conf XSendFilePath /var/www/mysite/uploadsДля debian squeeze просто добавляем в .htacess две директивы...
# enable xsendfile XSendFile On XSendFileAllowAbove onБез этих двух вариантов директив XSendFileAllowAbove и XSendFile вы будете получать различные ошибки, или закачку файлов длинной 0 байт. Ошибки сервера смотрим
cat /var/log/apache2/error.logК слову, директива XSendFileAllowAbove устарела и в новой версии модуля ее нет.
Комментариев нет:
Отправить комментарий