En muchas ocasiones no queremos que la gente pueda acceder a nuestros archivos directamente, no sin pasar primero por nuestra página. En este tutorial os presentaré una manera de hacerlo.

Lo que haremos será crear una “redirección” al archivo en PHP, así el usuario no podrá en ningún caso saber realmente donde está el archivo o como se llama.


<?php

if (!isset($_GET['i']) || empty($_GET['i'])) {
exit();
}
$root = "descargas/";
$file = basename($_GET['i']);
$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.");
}

?>

Con esto conseguimos que al pasarle por GET un nombre de archivo, lo busque en el directorio “descargas”, quedando nuestro enlace como algo así “www.midominio.es/?archivo.rar” (teniendo en cuenta que el archivo de php se llame index.php)

Pero nosotros no nos quedaremos aquí, iremos un paso mas allá. Ahora mismo estamos pasando por GET el nombre del archivo, pero,¿ y si en lugar del nombre, le pasamos una ID y guardamos en una base de datos el nombre del archivo vinculado a esa ID?

Podríamos guardar en una tabla algo como esto:

z97xht - archivo1.rar
z9467 - archivo2.rar
zsd3ht - archivo3.rar
456b6 - archivo.3rar

Y realizar consultas a la base de datos para poder encontrar el archivo, de manera que nuestro enlace sería así: “www.midominio.es/?z97xht”

Entonces modificaríamos un poco el código del script para que quedara de la siguiente manera:


<?php

if (!isset($_GET['i']) || empty($_GET['i'])) {
exit();
}
$conn = mysql_connect("dbhost", "dbuser", "dbpass") or die('Could not connect: ' . mysql_error());
$dbselect = mysql_select_db("dbname") or die ('Could not select database');
$idfile = $_GET['i'];
$nombrearchivo = mysql_query("SELECT `nombre_archivo` FROM `descargas` WHERE `id`='$idfile'");
$row = mysql_fetch_row($nombrearchivo);

$root = "descargas/";
$file = basename($row[0]);
$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.");
}

?>

Lo ideal es que crees un subdominio (por ejemplo d.kazike.es) a través del cual gestionar las descargas y que en ese subdominio tengáis este script llamándolo index.php (así nos podemos ahorrar escribir el nombre del archivo y usarlo como d.kazike.es/?ID)

Ya como ultima vuelta de tuerca, vamos a poner una comprobación de dominio,  para asegurarnos que no enlazan a nuestros archivos desde fuera. El PHP sería así y debería ir al principio del script:

if (strpos($_SERVER['HTTP_REFERER'],"kazike.es") == false){
header("Location: http://www.kazike.es");
}

Así si nos enlazan desde fuera, al no venir desde nuestra página, los enviaremos a nuestra página principal.

  1. Adhara

    en noviembre 9th en 15:11

    Uau! Felicidades por el blog, te está quedando muy bien y profesional!

  2. kazike

    en noviembre 9th en 18:51

    Muchas gracias!
    Voy poniendo cosas que me comentan que pueden estar interesantes. :)