2011-05-01 16 views
6

En mi sitio, dejo que los usuarios carguen archivos.Nombramiento de archivos cargados en la convención

Si el archivo es válido y se carga, se mueve a una carpeta (usando PHP).

Todos los usuarios cargan en la misma carpeta.

Creo que necesito cambiar el nombre de los archivos cargados.

¿Hay algo así como una convención de nomenclatura predeterminada que permita a los usuarios subir archivos con el mismo nombre de archivo?

Respuesta

16

No hay convenciones estándar, pero hay un par de buenas prácticas:


La organización de sus archivos en (usuario y/o fecha) carpetas Aware

Algo así como:

/uploads/USER/ or 
/uploads/[USER/]YEAR/[MONTH/[DAY/[HOUR/[MINUTE/]]]] 

Esto tendrá algunos beneficios:


(No) Cambio de nombre/desinfección Los nombres de archivo

cambio de nombre o no es una elección que tendrá que hacer , dependiendo de su sitio web, base de usuarios, cuán oscuro le gustaría ser y, obviamente, su arquitectura. ¿Prefiere tener un archivo llamado kate_at_the_beach.jpg o 1304357611.jpg? Depende de usted decidir, pero los motores de búsqueda (evidentemente) le gustan mejor al primero.

Una cosa que debe hacer es siempre desinfectar y normalizar los nombres de archivo, personalmente sólo permitiría a los siguientes caracteres: 0-9, a-z, A-Z, _, -, . - si elige este alfabeto saneamiento.la normalización básicamente significa simplemente convertir el nombre de archivo a mayúscula o minúscula (para evitar la pérdida de archivos si, por ejemplo, se pasa de un sistema de archivos sensible a mayúsculas a minúsculas a uno insensible a mayúsculas y minúsculas, como Windows).

Aquí hay un código de ejemplo que utilizo en phunction (enchufe descarado, sé : P):

$filename = '/etc/hosts/@Álix Ãxel likes - beer?!.jpg'; 
$filename = Slug($filename, '_', '.'); // etc_hosts_alix_axel_likes_beer.jpg 

function Slug($string, $slug = '-', $extra = null) 
{ 
    return strtolower(trim(preg_replace('~[^0-9a-z' . preg_quote($extra, '~') . ']+~i', $slug, Unaccent($string)), $slug)); 
} 

function Unaccent($string) // normalizes (romanization) accented chars 
{ 
    if (strpos($string = htmlentities($string, ENT_QUOTES, 'UTF-8'), '&') !== false) 
    { 
     $string = html_entity_decode(preg_replace('~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|tilde|uml);~i', '$1', $string), ENT_QUOTES, 'UTF-8'); 
    } 

    return $string; 
} 

Gestión de duplicados de nombres de archivo

Como la entrada documentación sobre move_uploaded_file() estados:

Si ya existe el archivo de destino , se sobrescribirá.

Por lo tanto, antes de llamar a move_uploaded_file() es mejor que ver si el archivo ya existe, si lo hace, entonces debería (si no quiere perder su archivo antiguo) cambiar el nombre del nuevo archivo, normalmente añadiendo un tiempo/aleatoria símbolo/única antes la extensión del archivo, hacer algo como esto:

if (file_exists($output . $filename) === true) 
{ 
    $token = '_' . time(); // see below 
    $filename = substr_replace($filename, $token, strrpos($filename, '.'), 0); 
} 

move_uploaded_file($_FILES[$input]['tmp_name'], $output . $filename); 

esto tendrá el efecto de insertar la $token antes de la extensión de archivo, como he dicho anteriormente. En cuanto a la elección del valor $token tiene varias opciones:

  • time() - asegura la unicidad de cada segundo, pero chupa el manejo de archivos duplicados
  • aleatoria - no es una idea muy buena, ya que no hace garantizar la singularidad y no maneja duplicados
  • única - usando un hash de los archivos contenidos es mi favorito enfoque, ya que garantiza contenido singularidad y le ahorra espacio en disco duro, ya que sólo tendrá como máximo 2 archivos idénticos (uno con el nombre de archivo original y otra con el hash anexado), código de ejemplo:

(el texto de relleno de manera que la siguiente línea se formatea como código.)

$token = '_' . md5_file($_FILES[$input]['tmp_name']); 

espero que ayude! ;)

+1

Muy útil de hecho. Especialmente el límite de archivos por carpeta. Y realmente me gusta la idea de crear hash de archivos. – PeeHaa

+0

¡Simplemente una gran respuesta! –

3

No existe tal convención, pero por lo general, el nombre se genera aleatoriamente para que las suposiciones sean menos probables. Permitir que el nombre de archivo sin desinfectar se desaconseje enérgicamente, tome al menos un enfoque de lista blanca en el que elimine todos los caracteres, excepto los de la lista blanca. La clave es la seguridad, la carga es una característica arriesgada y puede ser peligrosa si no se maneja adecuadamente.

2

Solo haga algunas convenciones internamente usted mismo. Por ejemplo, simplemente puede almacenar los archivos como userId_timestamp en la carpeta y mantener el nombre de archivo original en alguna base de datos. O simplemente lo hace userId_originalFilename o alguna otra combinación de cosas que lo hacen único.

0

¿Podría utilizar alguna combinación del nombre del usuario y la fecha de carga?

1

En un caso similar, guardo la información en una tabla (con el ID de usuario como clave externa), formateo el ID autónomo con ceros iniciales para el nombre de archivo (es decir, 000345.jpg) y almaceno el nombre original en la tabla .

+0

Por supuesto, esto es por una cantidad "razonable" de archivos. De lo contrario, podría usar algunas carpetas de agrupación de nivel superior, como nombre de usuario o ID de usuario. – morgar

Cuestiones relacionadas