En ocasiones necesitamos que el enlace a un archivo, que insertamos en una página web, sea para descargar y no para ser visualizado en el navegador. Esto se puede hacer utilizando una tecnología del lado del servidor, como puede ser PHP.
DOS formas de hacerlo
1. Método Básico
Creamos un archivo llamado, por ejemplo, descargar.php, en el que insertaremos el siguiente código:
<?php $file = $_GET['file']; header("Content-disposition: attachment; filename=$file"); header("Content-type: application/octet-stream"); readfile($file); ?> |
Con “Content-disposition: attachment; filename=$file” indicamos que el archivo se debe mostrar como adjunto (attachment).
Para crear el enlace insertaremos, por ejemplo, el siguiente código:
<a href="descargar.php?file=archivo.txt">Descargar</a> |
2. Método + Seguro
El script anterior, no sólo descarga el archivo indicado en el enlace, si no que además permite descargar cualquier archivo del servidor. Por ejemplo, cualquiera podría descargar nuestro archivo index.php con solo cambiar la ruta de descarga por descargas.php?file=../index.php.
Con el siguiente código, evitaremos lo anterior y además, comprobaremos que el archivo existe, para evitar errores en caso de que el archivo no exista.
Modificaremos el archivo descargas.php y sustituiremos todo su código por el siguiente:
<?php if (!isset($_GET['file']) || empty($_GET['file'])) { exit(); } $root = "archivos/"; $file = basename($_GET['file']); $path = $root.$file; $type = ''; if (is_file($path)) { $size = filesize($path); if (function_exists('mime_content_type')) { $type = mime_content_type($path); } else if (function_exists('finfo_file')) { $info = finfo_open(FILEINFO_MIME); $type = finfo_file($info, $path); finfo_close($info); } if ($type == '') { $type = "application/force-download"; } // Definir headers header("Content-Type: $type"); header("Content-Disposition: attachment; filename=$file"); header("Content-Transfer-Encoding: binary"); header("Content-Length: " . $size); // Descargar archivo readfile($path); } else { die("El archivo no existe."); } ?> |
La función basename() devuelve únicamente el nombre del archivo, eliminando cualquier ruta, para que no se puedan descargar archivos de otras carpetas del servidor.
Con la variable $root se define la carpeta donde se encuentran los archivos para descargar.
Referencias
Configuración de privacidad y de cookies.
Deja una respuesta