2010-02-25 8 views
6

Al cargar nuevas fotos a un servidor Linux con PHP, tengo que darles nombres únicos (se descarta usar su nombre de archivo). No hay interacción con un DB, por lo que tampoco es posible obtener ID únicos.¿Cómo se generan nombres de archivo cortos para las fotos cargadas?

Pensé en usar DATE + TIME.jpg, pero eso es demasiado tiempo.

¿Cuál es el mejor método para crear los nombres únicos más cortos posibles con PHP?

Respuesta

8

Utilice tempnam().

$filename = tempnam ($dir, $prefix) 

Crea un archivo con un nombre único en el directorio especificado. El nombre del archivo generado es bastante corto y se garantiza que será único.

+0

El archivo generado no tiene una extensión y agregar una extensión manualmente rompe la garantía de exclusividad. – Farhadi

0

Si yo fuera usted solo generaría un número aleatorio de unos 6 caracteres de longitud, y lo haré en un bucle do {} (while) hasta que sea único.

0

Una forma es simplemente usar nombres de archivo aleatorios. Me gusta rand(0,99999999)+".jpg". La probabilidad de una colisión es muy pequeña (si no tienes MUCHAS imágenes), y podrías comprobar fácilmente si por alguna extraña casualidad el nombre ya está tomado y obtener uno nuevo en ese caso.

+0

Recomendaría encarecidamente esto: dependiendo de cómo se siembra el generador de números aleatorios, es posible que se encuentre con colisiones sorprendentemente rápidas. –

2

También podría usar el mismo tipo de hash que utilizan los acortadores de URL como bit.ly para generar sus nombres únicos de carpeta de 5 caracteres (por ejemplo, bit.ly/x3hs0).

There's an implementation in PHP here.

0

La más corta no es la mejor manera. Creo que puede usar la función md5 ($ date + $ time) para obtener el nombre único del archivo. Será así: 8d41627e46d5b8556d0d3e30ec15538e.

También, si usted piensa que no habrá grandes recuento de los archivos cargados, se puede dividir la estructura de directorios de la carpeta con los nombres, por ejemplo, consta de 2 primeras cartas de md5() de hash:

8d/ 
    + 8d41627e46d5b8556d0d3e30ec15538e.jpg 
    + 8d897234ed899a523c88273c009c12c2.jpg 
ce/ 
    + ce2389898ace097cc667e134abb61729.jpg 
... 
1

Crea un archivo de índice; este archivo contiene la última ID que se usó para un archivo. Cuando un nuevo archivo debe ser creado:

  1. bloquear el archivo de índice (si su sistema operativo es compatible)
  2. Leer el ID
  3. Añadir 1 a la ID
  4. Guardar el archivo
  5. desbloqueo el archivo
  6. crear un archivo con ese ID

cordiales,
Stijn

+0

Se recomienda no hacerlo, ya que entonces ** es ** muy fácil para otros simplemente navegar por sus imágenes simplemente cambiando el número (que puede no ser el que usted desea). –

+0

Verdadero; si no quieres esto, solo usar números aumentados no es una opción. Aunque también podría aumentarlo en 13 por ejemplo en lugar de 1; o agregue el primer dígito de la identificación actual, ... –

1

Bueno, el problema es que desea algo único Y corto. Realmente no puedes tener ambos.

La representación más densa de un número aleatorio que sea legible por el ser humano sería algo así como base64 (sustituya los caracteres válidos para cualquier carácter que no debería estar en un nombre de archivo). Sin embargo, eso todavía significará que hay "solo" 64 variaciones para cada carácter en el nombre del archivo.

Si desea un nombre de archivo simple, simplemente use un número incremental y codifíquelo en base64 (rellene si desea una longitud mínima para el nombre). Si desea que no se pueda adivinar, necesita un generador de números aleatorios, pero luego debe asegurarse de evitar los dobles o terminará sobrescribiendo el archivo. Esta posibilidad de desastre es mayor cuanto más cortos son los nombres.

Probablemente pueda usar su propio equivalente personalizado de base64 con más caracteres que solo los 64 proporcionados por esa codificación, pero luego deberá verificar qué es lo que su sistema operativo considera un nombre de archivo válido y aún deberá asegurarse el cliente puede acceder a él correctamente (si no es solo un almacén de datos temporal). La forma más fácil de hacerlo es crear una cadena con cada carácter que quieras que sea legítimo y luego convertir la base del número en la longitud de la cadena (hay explicaciones de conversión básica en Google si no sabes como hacer eso). Eso permitiría una densidad de información aún mayor y nombres de archivo incluso más cortos.

3

La forma más segura es usar la función uniqid().

0

Se puede utilizar un número aleatorio y la schem fecha + hora y comprobar si el nombre existe desde hace tiempo() bucle:

$new_name = md5(rand(0,99999) . date('Ymd') . microtime(true)) . $extension; 
while (file_exists($path . $new_name)) 
    $new_name = md5(rand(0,99999) . date('Ymd') . microtime(true)) . $extension; 

donde $ new_name es el nombre corto del archivo subido

$ extensión es la extensión de archivo que (como .jpg)

$ ruta es la ruta completa de la directorio en el archivo tiene que ser salvado

El uso de rand() más microtime (verdadero) inscrease la oportunidad de encontrar un nombre único para el primer disparo ...

1

lo que siempre hago se establece el nombre del archivo como un hash MD5 del archivo en sí; el efecto secundario de esto es que evita que las cargas duplicadas ocupen espacio, además de que puede verificar la integridad de los datos con bastante facilidad.

Si quiere que sea más corto puede comenzar a cortar trozos del extremo, pero cuanto más lo haga, más se arriesga a una colisión de nombre de archivo, pero por experiencia, tomar los primeros ocho o más caracteres generalmente garantiza la exclusividad proporcionada no cargas demasiado

Cuestiones relacionadas