Hace un tiempo me encontré en la situación de enviar al browser archivos que tenía almacenados sin que el usuario pudiera ver la carpeta (o ruta) en que se encontraban almacenados.
Aunque esta práctica es bastante habitual, me encontré con la dificultad de que los nombres de los archivo podían contener caracteres “extraños”, como son los tildes, ñ, espacios y otros caracteres similares.
Al enviar estos archivos al cliente, dependiendo del browser, los nombres de los archivos se veían correctamente o presentaban caracteres codificados y/o erróneos.
Investigando, me encontré con que cada browser manejaba de forma diferente la forma en que recibían el nombre de los archivos por medio de la instrucción de PHP “header” y, a raíz de esto, debí programar la rutina en PHP que realiza esta conversión.
A continuación el código, que pueden complementar con la lectura de sus datos del archivo desde BD.
= 7.0)
return "IE";
}
return "Other";
}
/*Limpiamos cualquier salida de basura*/
ob_end_clean();
/* Inicio envío del nombre del archivo según browser */
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
/*Este nombre lo podríamos leer desde BD*/
$archnreal = "Nombre_del_archivo.txt";
/*La ruta también podríamos leerla desde BD*/
$path = "Ruta_al_Archivo/" . $archnreal;
$formatRFC2231 = 'Content-Disposition: attachment; filename*=UTF-8\'\'%s';
$formatDef = 'Content-Disposition: attachment; filename="%s"';
$format = "";
switch (detectUserAgent())
{
case "Opera":
case "Firefox": $archnreal = rawurlencode($archnreal);
$format = $formatRFC2231; break;
case "IE":
case "Chrome": $archnreal = rawurlencode($archnreal);
$format = $formatDef; break;
default:
if (function_exists('iconv'))
$archnreal = @iconv("UTF-8", "ISO-8859-1//TRANSLIT", $archnreal);
$format = $formatDef;
}
header(sprintf($format, $archnreal));
/* Fin envío del nombre del archivo según browser */
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: '.filesize($path));
ob_clean();
flush();
readfile($path);
?>