12 Febrero 2008 14 Comments

Forzar descargas con PHP

Introducción

Muchas veces navegando, nos encotnramos con sitios web que contienen enlaces hacia archivos como ser MP3, JPG, PDF, etc.

Cuando hacemos click en estos enlaces, por lo general se abren directamente, o sea, los MP3 en nuestro reproductor de audio, los PDF en el Acrobat Reader (o dentro del navegador), los JPG en el visor de imágenes, etc.

Lo que sucede, es que puede que nosotros queramos que el archivo no se abra automaticamente, sino que aparezca la típica ventana de descarga.

Código

Para lograr el resultado deseado, debemos crear un archivo llamado descargar.php (o como queramos) y ubicarlo en el directorio del hosting donde se encuentran nuestros archivos.

PHP:
  1. <br />
  2. <?php<br />
  3.     //  descargar.php<br />
  4.     $f = $_GET["f"];<br />
  5.     header("Content-type: application/octet-stream");<br />
  6.     header("Content-Disposition: attachment; filename=$f");<br />
  7.     $fp=fopen("$f", "r");<br />
  8.     fpassthru($fp);<br />
  9. ?><br />

Implementación

El modo de uso es realmente sencillo, solo debemos modificar el destino de nuestro enlace de archivo.jpg a descargar.php?f=archivo.jpg.

Quedando en enlace de la siguiente manera:

HTML:
  1. <br />
  2. <a href="descargar.php=?archivo.jpg">Descargar Imagen</a><br />

La verdad es que es un método muy facil de implementar y que nos brinda una solución frente a este problema.

A mi gusto debería implementarse en los sitios web con enlaces hacia archivos PDF, ya que generalmente cuando abrimos uno o varios de estos, el navegador comienza a ponerse muy lento.

Fuente | DaveMM

ACTUALIZACIÓN

Corey me informa que corrigió un bug de seguridad en su código que permitía la descarga de cualquier tipo de archivos por medio del script, como archivos PHP por ejemplo.
Para corregirlo, usamos el código actualizado:

PHP:
  1. <?php
  2.     $f = $_GET["f"];
  3.     $archivos = array('.mp3','.jpg','.pdf');
  4.     $extension = strtolower(strstr($f,'.'));
  5.     if(strpos($f,'/')!==false)
  6.         exit("Los archivos de otros <b>directorios</b> no son descargables.");</p>
  7.     if(!in_array($extension,$archivos))
  8.         exit("Los archivos con extensión <b>$extension</b> no son archivos descargables.");
  9.     header("Content-type: application/octet-stream");
  10.     header("Content-Disposition: attachment; filename=$f");
  11.     $fp=fopen("$f", "r");
  12.     fpassthru($fp);
  13. ?>

Ahora, con el uso de la variable $archivos, podemos facilmente definir las extensiones de los archivos que deseamos permitir descargar.

Mas información en la entrada oficial

14 Responses to “Forzar descargas con PHP”

  1. Davemm 13 Febrero 2008 at 0:17 #

    Da gusto saber que te pasas por mi sitio :) …que te parece si intercambiamos enlaces?, yo te enlazo, tu me enlazas. Cualquier cosa me avisas.Saludos.

  2. nicoh 13 Febrero 2008 at 22:17 #

    Listo, ya te enlacé.

    Gracias :61:

  3. Davemm 13 Febrero 2008 at 22:23 #

    Gracias, te agrego a mi blogroll de inmedianto; solo una cosa, me gustaria que me pusieras como “Davemm”, no DaveMM”. Saludos.

  4. Juanu 13 Febrero 2008 at 22:29 #

    Muuuuuuy bueno che!
    Un abrazo Nico

  5. nicoh 13 Febrero 2008 at 23:26 #

    Ok, gracias a los dos!

  6. Davemm 17 Febrero 2008 at 2:01 #

    Actualicé el Script, pasate por mi Blog. Saludos.

  7. nicoh 17 Febrero 2008 at 2:56 #

    Gracias Corey (David), ya actualicé el post.

    Suerte

  8. marcelo 27 Febrero 2008 at 0:50 #

    muy bueno el blog, que libreria utilizas para que el codigo se vea asi de bonito.. jajasaludos!

  9. nicoh 27 Febrero 2008 at 12:50 #

    Es un plugin llamado iG:Sintax Hiliter,

    Suerte :6:

  10. Animevsartistas 16 Abril 2008 at 22:34 #

    hola esta todo genial ….. pero lo que pasa en mi caso es que! hago para que mi URL o direccion de donde jalo mi archivo no se note, es decir que no vean de sale la descarga la direccion
    <a href=”descargar.php=? http://nicolasbermani.com.ar/musica.mp3” rel=”lightbox”>Descargar Imagen</a><br />
     
    se supone que tengo que poner asi pero no quiero que se note mi URL de mi hosting….OJALA ME AYUDEN LES ESTARIA AGARADECIDO

  11. Guille 23 Abril 2008 at 10:05 #

    Hey! menos mal que avisaste del problemita de seguridad, imaginate si te bajan too tu sitio en php…un bajon.bueno, soy guille socio junto con ana de http://chiflame.net/, el meneame argentino

  12. nicoh 23 Abril 2008 at 23:06 #

    Y si avisé.. por eso edité el post y resalté la actualización  :|

  13. DJ.cangu 7 Julio 2008 at 0:45 #

     

  14. Rafael 13 Noviembre 2009 at 0:54 #

    Muy buen código, ya lo he implementado, solo que tengan cuidado en la linea No. 6 hay que quitar “” que esta al final(hablo del código actualizado), sino el php les da parser error. Por si andan cortos con el php.

    Siguiendo el ejemplo, con el nuevo código la implementación quedaría así:
    Descargar Imagen

    Saludos ;-)


Leave a Reply