2009-08-11 10 views
5

estoy generar un nombre de archivo único para los archivos cargados con el siguiente códigoGeneración de un nombre de archivo único basado en el tiempo para la carga sin crear una condición de carrera

$date = date('U'); 
$user = $_SERVER[REMOTE_ADDR]; 
$filename = md5($date.$user); 

El problema es que quiero utilizar este nombre de archivo nuevo más adelante en el guión, pero si el guión tarda un segundo en ejecutarse, voy a obtener un nombre de archivo diferente la segunda vez que intento usar esta variable.

Por ejemplo, estoy usando un script de carga/cambio de tamaño/guardar imagen cargada. La primera operación del script es copiar y guardar la imagen redimensionada, que utilizo una función de fecha para asignarle un nombre único. A continuación, el script procesa el guardado y guarda la carga completa, y le asigna un nombre. Al final del script ($thumb y $full son las variables), necesito insertar en una base de datos MySQL, los nombres de archivo que utilicé cuando guardé las cargas. El problema es que a veces en imágenes grandes tarda más de un segundo (o durante el proceso, los segundos cambian) dando como resultado un nombre de archivo diferente al de la base de almacenamiento del archivo.

¿No es una buena idea utilizar este método de nomenclatura?

Respuesta

5

AFAIK es una gran manera de nombrar los archivos, aunque podría marcar file_exists() y tal vez marcar un número al azar.

Debe almacenar ese nombre de archivo en una variable y volver a consultarlo más tarde, en lugar de confiar en el algoritmo cada vez. Esto podría almacenarse en el usuario $_SESSION, una cookie, una variable GET, etc. entre pageloads.

Esperamos que ayuda

+1

Esto parece abordar la pregunta real que no se trata de "cómo puedo generar un nombre único" sino más bien "cómo evito generar el nombre dos veces". – Lucky

0

Por qué no usar

$filename = md5(rand()); 

Esto será más o menos único en todos los casos. Y si encuentra que $filename ya existe, puede simplemente llamarlo nuevamente.

+1

rand() será "bastante" único, pero $ date. $ Time será único. Por qué intercambiar uno por el otro, y además de esto no aborda la cuestión real. – Lucky

2

recomendaría almacenar el nombre del archivo en la sesión (como por IA). Si lo almacena en una de las otras variables, es más probable que el usuario final pueda atacar el sistema a través de él. MD5 del usuario concatenado con rand() sería una buena forma de obtener una larga lista de valores únicos. El solo uso de rand() probablemente tenga un mayor porcentaje de conflictos.

No estoy seguro del proceso que está siguiendo para cargar archivos, pero otra forma de manejar las cargas de archivos es con los controladores integrados de PHP. Puede cargar el archivo y luego usar los métodos "seguros" para extraer los archivos cargados del espacio temporal. (el espacio temporal en este caso se puede ubicar de forma segura fuera de la directiva de directorio base abierto para evitar manipulaciones). is_uploaded_file() y move_uploaded_file() desde: http://php.net/manual/en/features.file-upload.post-method.php ejemplo 2 podría manejar el problema que está encontrando.

Definitivamente, compruebe si hay un archivo existente en esa ubicación si elige un nombre de archivo sobre la marcha. Si la entrada del usuario está permitida en cualquier forma o forma, valide y filtre el argumento para asegurarse de que sea seguro. Además, si la carpeta de almacenamiento es accesible desde la web, asegúrese de incluir el nombre y probablemente también la extensión. No quiere que alguien pueda cargar el código y luego pueda ejecutarlo. Eso oficialmente conduce a actividades MALAS.

2

Solo quiero añadir que php tiene una función para crear identificadores: uniqid. También puede prefijar el identificador con una cadena (¿fecha quizás?).

¡Siempre valide la entrada de su usuario y las cabeceras del servidor!

0

No es una buena idea usar ID dependiente del tiempo: si carga dos imágenes al mismo tiempo, la última puede sobrescribir la anterior. Debería ver funciones como uniqid(). Sin embargo, si este script de carga/cambio de tamaño/guardar está destinado a ser "único usuario", entonces este no es un problema tan grande.

Para el problema en sí. Si yo fuera tú, simplemente guardaría el nombre de archivo calculado en alguna variable y usaría la variable desde ese punto. La computación ya calculada es pérdida de tiempo. Y al subir algunas imágenes realmente grandes, o más imágenes a la vez, el script puede tomar incluso 20 segundos. No puede depender del hecho de que hará todo lo que quiera en un segundo.

Cuestiones relacionadas