A free and open-source book on ZF3 for beginners

Translation into this language is not yet finished. You can help this project by translating the chapters and contributing your changes.

4.16. Desactivar la Impresión de la Vista

Algunas veces necesitamos desactivar la impresión de las plantillas por defecto. Para hacer esto solo regresamos el objeto Response desde la acción del controlador.

Por ejemplo, vamos a crear la clase DownloadController y agregar la acción "file" que permitirá a los usuarios del sitio descargar archivos desde nuestro sitio web. Esta acción no necesita la correspondiente plantilla de vista file.phtml porque esta solo vuelca el contenido del archivo en el flujo de salida estándar de PHP.

Agregamos el archivo DownloadController.php a la carpeta Controller del módulo Application y luego colocamos el siguiente código dentro del archivo:

<?php
namespace Application\Controller;

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

/**
 * This is the controller class for managing file downloads.
 */
class DownloadController extends AbstractActionController
{
    /**
     * This is the 'file' action that is invoked
     * when a user wants to download the given file.
     */
    public function fileAction()
    {
        // Get the file name from GET variable
        $fileName = $this->params()->fromQuery('name', '');

        // Take some precautions to make file name secure
        $fileName = str_replace("/", "", $fileName);  // Remove slashes
        $fileName = str_replace("\\", "", $fileName); // Remove back-slashes

        // Try to open file
        $path = './data/download/' . $fileName;
        if (!is_readable($path)) {
            // Set 404 Not Found status code
            $this->getResponse()->setStatusCode(404);
            return;
        }

        // Get file size in bytes
        $fileSize = filesize($path);

        // Write HTTP headers
        $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");

        // Write file content
        $fileContent = file_get_contents($path);
        if($fileContent!=false) {
            $response->setContent($fileContent);
        } else {
            // Set 500 Server Error status code
            $this->getResponse()->setStatusCode(500);
            return;
        }

        // Return Response to avoid default view rendering
        return $this->getResponse();
    }
}

El método de acción toma el parámetro name desde la parte de consulta de la URL (línea 19), remueve las barras del nombre del archivo (líneas 22-23), agrega las cabeceras HTTP al objeto Response (líneas 39-45) y el contenido del archivo (líneas 48-55). Finalmente, regresamos el objeto Response y así desactivar la impresión de la vista por defecto.

Registramos la clase DownloadController agregando la siguiente línea al archivo module.config.php:

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

Además, necesitaremos agregar la ruta al archivo module.config.php (una ruta le dice a ZF3 a que URL le corresponde que acción en el controlador). Modificamos la llave routes del archivo de configuración de la siguiente manera:

<?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',
                    ],
                ],
            ],
        ],
    ],
  // ...
];

Para ver como funciona la descarga del archivo creamos la carpeta APP_DIR/data/download y colocamos un archivo de texto llamado sample.txt en ella. Luego abrimos el navegador web y escribimos la URL "http://localhost/download/file?name=sample.txt" en nuestra barra de navegación del navegador web y presionamos la tecla Enter. El navegador descargará el archivo sample.txt y ofrecerá guardarlo en alguna parte.


Top