Como forzar la descarga de archivos con PHP

En algunos contextos quizá es necesario que el usuario descargue un archivo pdf, xls, csv, etc, para ver más información en otros formatos legibles en el ordenador o incluso con el objetivo de ser impresos. Los navegadores de hoy en día muestran directamente algunos tipos de ficheros en el navegador antes de descargarlo y quizá puede ser molesto si lo que deseamos es descargarlo directamente nada más pulsar en el enlace o botón.

En este artículo vamos a ver un ejemplo de como conseguir tal efecto. Explicaremos un ejemplo para descargar directamente un archivo en formato csv que deberá estar previamente depositado en el servidor.

Allí donde deseemos dentro de la etiqueta <body> añadiremos un enlace del estilo:

<a href="index.php?download_csv=1">Descargar archivo csv</a>

 

Después tan solo necesitaremos añadir el código PHP de control de la descarga en el mismo fichero o donde controlemos las acciones del usuario:

if (isset($_GET['download_csv'])) {
    $file_example = 'example.csv';
    if (file_exists($file_example)) {
        header('Content-Description: File Transfer');
        header('Content-Type: text/csv');
        header('Content-Disposition: attachment; filename='.basename($file_example));
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate');
        header('Pragma: public');
        header('Content-Length: ' . filesize($file_example));
        ob_clean();
        flush();
        readfile($file_example);
        exit;
    }
    else {
        echo 'Archivo no disponible.';
    }
}

 

Lo primero que hacemos es comprobar que se haya pulsado en el enlace que contenga el parámetro de tipo GET «download_csv» con el simple objetivo de gestionar la descarga. Especificamos la ruta del fichero depositado en el servidor en la misma raiz del fichero que se ejecuta y comprobamos si existe para descargarlo.

A continuación especificamos información sobre el fichero para informar al navegador.

La función header() es imprescindible. Con ella conseguimos especificar e informar al navegador algunos datos relevantes para la descarga.

En este caso estamos indicando que:

  • deseamos hacer una transferencia de archivo
  • el tipo de archivo a procesar sea csv
  • se trata de un archivo adjunto
  • el tipo de codificación utilizada

Al final del script enviamos las cabeceras, limpiamos el buffer y abrimos el archivo que mostrará la ventana de descarga:

Ver ejemplo en funcionamiento

Autor
Escrito por Jose Aguilar - Director ejecutivo y tecnológico en JA Modules. Experto programador PrestaShop y Experto programador WordPress.
Te ha servido? Valora esta entrada!
(8 votos, promedio: 5 de 5)
Comparte en las redes sociales
¿Buscas trabajo de programador?

15 respuestas a “Como forzar la descarga de archivos con PHP”

  1. Dixán Pupo dice:

    Si filename=’.basename($file_example) no tiene comillas dará problemas cuando el nombre de un archivo tiene comas. Es mejor delimitar el nombre del archivo así: filename=»‘.basename($file_example).'» ‘).

  2. Gilberto Villarreal Rodriguez dice:

    //para los que no les funciona prueben con esto

    function download($fileName) {

    if (file_exists($fileName)){

    ob_clean();
    header(‘Content-Description: File Transfer’);
    header(‘Content-Type: text/csv’);
    header(‘Content-Disposition: attachment; filename=’.basename($fileName));
    header(‘Content-Transfer-Encoding: binary’);
    header(‘Expires: 0’);
    header(‘Cache-Control: must-revalidate’);
    header(‘Pragma: public’);
    header(‘Content-Length: ‘ . filesize($fileName));
    ob_end_clean();
    flush();
    readfile($fileName);
    return true;
    }else{
    $this->setMsg(__CLASS__.»::».__FUNCTION__, $fileName.» ¡Nose encontro el archivo!»);
    return false;
    }
    }

  3. Miguel dice:

    Hola … el código me funcionaba bien hasta un par de días atrás … pero ahora cuando descargo los archivos y al abrirlos me dice que se bajo el archivo dañado … esto empezó después que el hosting cambió a otro servidor del proveedor. Me dice el proveedor que está el servidor en regla y todo actualizado usando php 7.4 … que podrá ser?

  4. Juan Pérez dice:

    Hola buenas, excelente el código funciona perfecto, pero al utilizarlo con Jquery y Ajax no hace la descarga ¿existe alguna solución?

    Se agradece de antemano tu atencón

  5. Pedro dice:

    Se acerca ,mucho a lo que quiero , pero como seria si en vez de un cvs fuese un pdf…gracias

  6. Ericka dice:

    Tenia un problema que al descargar el archivo este se modificaba y se le agregaban al inicio espacios en blanco.
    Esto se solucionó al usar estas funciones ob_clean(); flush() Muchas gracias!!!

  7. xoceunder dice:

    como puedo sacar codigo fuente de php con la ruta

    • Jose Aguilar dice:

      Hola,

      Lamento decir que en este ejemplo no hay archivo para descargar pero todo el código está publicado y los puedes copiar y pegar en tu archivo php.

      Saludos

  8. Alexander dice:

    Hola, ¡Saludos!
    ¿Es posible descargar más e un archivo (2 o 3) enviados desde un array?

    Gracias de antemano,

  9. ip dice:

    La verdad es que si, depues de 2 dias con este problema de descarga el unico codigo que me ha servido ha sido el tuyo. muchas gracias por tu labor.

  10. 123 dice:

    Disculpa mi comentario grosero, me funciono excelente!!!.
    Gracias por el código. Fue el único código que sirvió, los demás que aparecen en Internet no sirven para una mierda.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Ver más sobre