A free and open-source book on ZF3 for beginners


4.16. Отключение рендеринга представления

Иногда вам придется отключать рендеринг представления, работающий по умолчанию. Чтобы это сделать, нужно просто вернуть объект Response из действия контроллера.

Например, давайте создадим класс DownloadController и добавим действие "file", которое позволит пользователям сайта скачивать файлы с вашего вебсайта. Это действие не нуждается в соответствующем шаблоне представления file.phtml, потому что оно выбрасывает содержимое файла в стандартный поток вывода PHP.

Добавьте файл DownloadController.php в директорию Controller модуля Application, затем вставьте в файл следующий код:

<?php
namespace Application\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;

/**
 * Это класс контроллера для управления загрузками файлов.
 */
class DownloadController extends AbstractActionController 
{
    /**
     * Это действие 'file', которое вызывается,
     * когда пользователь хочет скачать данный файл.     
     */
    public function fileAction() 
    {
        // Получить имя файла из GET-переменной
        $fileName = $this->params()->fromQuery('name', '');
	
        // Меры предосторожности, чтобы защитить имя файла
        $fileName = str_replace("/", "", $fileName);  // Убрать слеши
        $fileName = str_replace("\\", "", $fileName); // Убрать обратные слеши
	
        // Попытка открыть файл
        $path = './data/download/' . $fileName;
        if (!is_readable($path)) {
            // Поставить код состояния 404 Not Found
            $this->getResponse()->setStatusCode(404);            
            return;
        }
		
        // Получить размер файла в байтах
        $fileSize = filesize($path);

        // HTTP-заголовки
        $response = $this->getResponse();
        $headers = $response->getHeaders();
        $headers->addHeaderLine(
                 "Content-type: application/octet-stream");
        $headers->addHeaderLine(
                 "Content-Disposition: attachment; filename=\"" . 
			     $fileName . "\"");
        $headers->addHeaderLine("Content-length: $fileSize");
        $headers->addHeaderLine("Cache-control: private"); 
		
        // Содержимое файла
        $fileContent = file_get_contents($path);
        if($fileContent!=false) {                
            $response->setContent($fileContent);
        } else {        
            // Устанавливаем код состояния 500 Server Error
            $this->getResponse()->setStatusCode(500);
            return;
        }
	
        // Возвращаем Response, чтобы избежать рендеринга шаблона представления
        return $this->getResponse();
    }
}

Метод действия берет имя параметра из запроса URL (строка 19), убирает слеши из имени файла (строки 22-23), добавляет HTTP-заголовки объекту Response (строки 39-45) и содержимое файла (строки 48-55). Наконец, он возвращает объект Response, чтобы отключить рендеринг представления.

Зарегистрируйте класс DownloadController, добавив следующую строку в ваш файл module.config.php:

<?php
return [
    // ...    
    'controllers' => [
        'factories' => [
            // ...
            Controller\DownloadController::class => InvokableFactory::class
        ],
    ],    
     // ...
];

Вам также понадобится добавить маршрут к вашему файлу module.config.php. Измените ключ routes файла конфигурации следующим образом:

<?php
return [
    // ...    
    'router' => [
        'routes' => [
            // Add this route for the DownloadController
            'download' => [
                'type'    => Segment::class,
                'options' => [
                    'route'    => '/download[/:action]',
                    'defaults' => [
                        'controller'    => Controller\DownloadController::class,
                        'action'        => 'index',
                    ],
                ],
            ],
        ],
    ], 
    // ...
];

Чтобы посмотреть, как работает загрузка файлов, создайте директорию APP_DIR/data/download и положите туда текстовый файл с именем sample.txt. Затем откройте ваш браузер, введите адрес "http://localhost/download/file?name=sample.txt" и нажмите Enter. Браузер начнет загрузку файла sample.txt и предложит вам его куда-нибудь сохранить.


Top