Por: fael + Otros tutoriales de fael + 4 de Abril del 2006
Hacer descargables cualquier tipo de archivos no es muy complicado. La mayoría de las tecnologías del lado del servidor nos permiten hacer esto, en este caso veremos cómo es con PHP.
El script fue sacado del todopoderoso php.net y es el siguiente:
<?php $f = $_GET["f"]; header("Content-type: application/octet-stream"); header("Content-Disposition: attachment; filename=\"$f\"\n"); $fp=fopen("$f", "r"); fpassthru($fp); ?>
De esta forma, cuando necesitemos que el explorador quiera descargar, por ejemplo un archivo de imagen, lo llamaríamos descargar.php?f=imagen.jpg.
Y el navegador abrirá el diálogo de descarga:
Sencillo, no? Bien, pero podría haber serios problemas, dejar el script así podría hacer descargable cualquier tipo de archivo, incluyendo el código fuente de otros archivos php.
A continuación veremos cómo implementar algunas medidas de seguridad.
Aquí podemos tener dos opciones, enlistar los tipos de archivos que pueden ser descargables o listar las extensiones de los archivos que podemos descargar.
Además, para evitar que se pueda navegar en otros directorios, vamos a implementar una comprobación.
Útil cuando son relativamente pocos los archivos descargables, los nombres los metemos en un arreglo y hacemos una sencilla comprobación y listo.
<?php $archivos = array("imagen.jpg", "logo.png", "flash.swf"); $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); ?>
De esta forma, si queremos descargar un archivo que no sean los que enlistamos en el arreglo, nos aparecerá el mensaje de error:
ERROR! no es posible descargar archivo.ext
Además este script es sensitivo a mayúsculas y minúsculas, no es lo mismo flash.swf que Flash.swf, fLaSh.SwF... etc
Pero qué pasa cuando tenemos 100 imagenes en formato jpg, png y gif que querramos que el usuario pueda descagar? Para eso usamos un filtrado de extensión.
La lógica es igual, usar in_array para saber si el archivo a descargar tiene una de las extensiones que hemos marcado como descargables, esto se hace con explode y count, seguramente habrá una forma más eficiente de hacerlo pero no la conozco.
<?php $extensiones = array("jpg", "jpeg", "png", "gif"); $f = $_GET["f"]; if(strpos($f,"/")!==false){ die("No puedes navegar por otros directorios"); } $ftmp = explode(".",$f); $fExt = strtolower($ftmp[count($ftmp)-1]); if(!in_array($fExt,$extensiones)){ die("<b>ERROR!</b> no es posible descargar archivos con la extensión $fExt"); } header("Content-type: application/octet-stream"); header("Content-Disposition: attachment; filename=\"$f\"\n"); $fp=fopen("$f", "r"); fpassthru($fp); ?>
Y con esto la descarga de archivos se hace más fácil y más segura. Espero les haya servido.
Si tienes alguna pregunta de este tutorial; puedes hacerla aqui en los foros