Forzar descargas de archivos con PHP

Pretendo forzar la descarga de archivos de extensión usual (doc, pdf, mp3...) de modo que no se abran desde el navegador del visitante con el programa asociado, sino que aparezca el típico cuadro con las opciones Abrir-Guardar-Cancelar. Sé que el comprimirlos sería una solución, pero no me sirve para lo que quiero y pretendo hacerlo con PHP, pero te confieso mi total ignorancia de este lenguaje.
En la red he encontrado multitud de scripts en PHP que hacen lo que pretendo pero algo hago mal y yo no lo consigo. Te explico lo que hago y me corriges:
-Copio en una página en blanco (utilizo Dreamweaver) cualquiera de estos scripts, por ejemplo:
<?php
    GET["f"];
    header("Content-type: application/octet-stream");
    header("Content-Disposition: attachment; filename=\"$f\"\n");
    $fp=fopen("$f", "r");
    fpassthru($fp);
?>
-O este otro que es el mismo pero mejorado para la descarga de archivos concretos:
<?php
    $archivos = array("encabezado.jpg", "logo.png", "concurso.mp3");
    $f = $_GET["f"];
    if(strpos($f,"/")!==false){
        die("No puedes navegar por otros directorios");
    }
    if(!in_array($f,$archivos)){
        die("<b>ERROR!</b> no es posible descargar $f");
    }
    header("Content-type: application/octet-stream");
    header("Content-Disposition: attachment; filename=\"$f\"\n");
    $fp=fopen("$f", "r");
    fpassthru($fp);
?>
-Lo guardo como una página PHP, por ejemplo, "descarga.php".
-En una página html incluyo en un hipervínculo "[size= 10pt; font-family: 'Trebuchet MS'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA]descarga.php?f=concurso.mp3 [/size]para lanzar la descarga. Lo único que consigo en todos los casos, probando con diferentes códigos, es que el archivo que se intenta descargar sea "descarga.php", pero no "concurso.mp3" como yo pretendo, con lo que interpreto que no se está leyendo el código PHP incluido dentro de la página, probablemente porque debe estar mal hecha.
Nuevamente agradecido.

1 Respuesta

Respuesta
1
El problema de lo que intentas hacer no es tanto si lo haces bien o mal, sino que desgraciadamente hay algo que está por encima:
La configuración de Internet Explorer para ciertos documentos.
Si un usuario de Internet Explorere abre un documento Word, la primera vez le pregunta si desea abrirlo dentro del explorador. Si el usuario dice que sí, esa configuración es la que permanece. Por mucho que tu envíes correctamente el fichero desde PHP, no te puedes saltar esa configuración 'del usuario' en Internet Explorer.
En otros navegadores sí te puede llegar a funcionar, pero claro, tu no sabes qué explorador tendrá el visitante...
Ante todo gracias por tu respuesta, David.
Entiendo y comparto lo que me dices de que Iexplorer siga abriendo determinados archivos directamente sin preguntar qué hacer con él una vez que se le ha indicado que lo abra la primera vez. Lo que ya no tengo tan claro es que esto esté por encima y se salte la orden de forzar la descarga si la hacemos desde PHP.
Cuando, como te decía en mi pregunta, hago una búsqueda, por ejemplo en Google, con "forzar descarga", en muchos de los códigos en PHP que se ofrecen para ello, se indica explícitamente que son para que el navegador (cualquiera de ellos), no se salte el cuadro de diálogo en los tipos de archivo más comunes (doc, pdf, jpg...) con las opciones Abrir - Guardar - Cancelar y abra el archivo directamente, sino para forzar a que aparezca. Por ejemplo, mira este que es el más básico, y los aclaraciones que incluye. Como ves son los dos header que se incluyen los que fuerzan la descarga.
<?php
//Cuando ponemos para su descarga ficheros, dependiendo de la extensión de los mismos el navegador
//puede abrirlos en vez de forzar su descarga. Tal es el caso de ficheros con extensiones como
//.doc, .html o .pdf. Por ejemplo, para forzar la descarga de un fichero PDF:
// El content type del fichero.
header("Content-Type: application/pdf");
// Decirle al navegador que el fiechero es descargable
// y ponerle un nombre.
header("Content-Disposition: attachment; filename=nombrefichero.pdf");
?>
En el ejemplo que se incluye al final de [size= 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA]http://www.martinandrino.com/index.php/2008/10/06/forzar-descarga-con-php/, concretamente, dentro de la página, en los hipervínculos <span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;"> y <span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;"> se consigue forzar la descarga (me funciona tanto en Iexplorer como en Firefox) mientras que en <span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;"> se abre la imagen directamente (luego entiendo que sí debe se posible forzar la descarga con PHP). El problema es que al intentar ver el ejemplo o descargarlo para ver el código no me deja, pues los hipervínculos para ello están rotos. He intentado hacerlo yo guardando en una página PHP el código que se incluye y lanzándola desde otra HTML como descarga.php?file=mi_imagen.jpg y el archivo para el que se me ofrece la descarga no es mi_imagen.jpg, sino descarga.php. Si en lugar de guardar le digo abrir me lo abre con Dreamweaver que es con quien los tengo asociados en mi equipo; si lo lanzo de nuevo, no me lo abre directamente, a pesar de haberlo abierto previamente, sino que me ofrece de nuevo el cuadro de diálogo de descarga. Lo mismo me ocurre si lo hago desde cualquier ordenador del trabajo[/size]</span></span></span>
[size= 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA]<span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;"><span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;"><span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;">He leido al detalle el tutorial para forzar descargas de archivos con PHP que aparece en <span style="font-size: 10pt; font-family: "Trebuchet MS"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman';">http://www.cristalab.com/tutoriales/forzar-descargas-con-php-c166l/ y siempre llego al mismo resultado que te comento.[/size]</span></span></span></span>
[size= 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA]<span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;"><span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;"><span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;"><span style="font-size: 10pt; font-family: "Trebuchet MS"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman';">En fin, que el tema me está llevando muchísimo tiempo y no encuentro la solución.[/size]</span></span></span></span>
[size= 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA]<span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;"><span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;"><span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;"><span style="font-size: 10pt; font-family: "Trebuchet MS"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman';">Me gustaría saber tu opinión sobre todo lo que te comento o si pudieras hacerme cualquier aclaración al respecto.[/size]</span></span></span></span>
[size= 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA]<span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;"><span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;"><span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;">[/size]</span></span></span>[size= 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA]<span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;"><span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;"><span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;"><span style="font-size: 10pt; font-family: "Trebuchet MS"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman';">Gracias y un saludo.[/size]</span></span></span></span>
[size= 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA]<span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;"><span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;"><span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;">[/size]</span></span></span>[size= 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA]<span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;"><span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;"><span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;"><span style="font-size: 10pt; font-family: "Trebuchet MS"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman';">Francisco García[/size]</span></span></span></span>
[size= 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA]<span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;"><span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;"><span style="font-size: 12pt; font-family: "Times New Roman"; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: ES; mso-fareast-language: ES; mso-bidi-language: AR-SA;">[/size]</span></span></span>
! Caramba, David! No entiendo por qué aparece aquí en cierre de la etiqueta "span" en lugar del texto que había escrito. Probablemente sea porque no se han pegado como texto plano las direcciones que incluía. Te lo escribo de nuevo lo que falta.
En el ejemplo que se incluye al final de http://www.martinandrino.com/index.php/2008/10/06/forzar-descarga-con-php se lanza la descarga desde los hipervínculos download.php?file=img01.jpg y download.php?file=../html/img01.jpg y aparece el cuadro para descargar, sin embargo, desde img01.jpg se abre directamente la imagen, tanto en Iexplorer como en Firefox (por eso creo que sí es posible forzar la descarga con PHP). La pena es que que cuando intento ver el ejemplo o descargarlo desde los hipervínculos que se ofrecen para acceder al código observo que los hipervínculos que lo permitirían están rotos. He intentado hacerlo yo incluyendo en una página PHP el código que se ofrece y lanzar la descarga desde otra HTML con el hipervínculo apuntando a descarga.php?file=mi_imagen.jpg, pero la descarga que se me ofrece en el cuadro no es la de mi_imagen.jpg sino la de descarga. php. Incluso si lo abro (en mi equipo los php estan asociados a Dreamweaver) y lanzo de nuevo la descarga, no se abre directamente, sino que sigue ofreciendo la opción Guardar.
También he leído al detalle el manual para forzar descargas con PHP que se ofrece en http://www.cristalab.com/tutoriales/forzar-descargas-con-php-c166l y siempre llego al mismo resultado que te vengo indicando.
En fin, el hecho es que el tema me está llevando mucho tiempo y no hay manera.
Me gustaría conocer tu opinión sobre lo que te comento y cualquier otra aclaración que pudieras hacerme.
Gracias y un saludo.
Francisco García
No sé si has progresado con el tema.
Por mi parte sigo opinando que si la configuración del explorador fuerza la visualización de la página, no podrás forzar la descarga.
Bueno, gracias David por analizar el tema. Si consiguiera alguna solución para el mismo, te la haré llegar.
Saludos.
Francisco García.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas