2009-08-11 6 views
5

sto generando un nome file univoco per i file caricati con il seguente codiceGenerazione di un nome di file univoco basato sul tempo per il caricamento senza creare una condizione di competizione

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

Il problema è che voglio usare questo nuovo nome di file più avanti nello script, ma se lo script impiega un secondo per essere eseguito, otterrò un nome file diverso la seconda volta che cerco di usare questa variabile.

Ad esempio, sto utilizzando uno script di upload/ridimensionamento/salvataggio dell'immagine. La prima operazione dello script è quella di copiare e salvare l'immagine ridimensionata, che io uso una funzione data per assegnare un nome univoco a. Quindi lo script processa il salvataggio e salva l'intero caricamento e gli assegna un nome. Alla fine del copione ($thumb e $full sono le variabili), ho bisogno di inserire in un database MySQL, i nomi dei file che ho usato quando ho salvato i caricamenti.

Il problema è che a volte su immagini di grandi dimensioni ci vuole più di un secondo (o durante il processo, i secondi cambiano) risultando in un diverso nome di file inserito nel database rispetto a quello in cui il file viene effettivamente salvato.

Non è una buona idea utilizzare questo metodo di denominazione?

risposta

5

AFAIK è un ottimo modo per assegnare un nome ai file, anche se dovrei controllare file_exists() e magari virare su un numero casuale.

È necessario memorizzare quel nome file in una variabile e fare nuovamente riferimento in un secondo momento, invece di fare affidamento sull'algoritmo ogni volta. Questo potrebbe essere memorizzato nell'utente $_SESSION, un cookie, una variabile GET, ecc. Tra i pageload.

Speranza che aiuta

+1

Questo sembra rispondere alla domanda effettiva che non riguarda "come si genera un nome univoco", ma piuttosto "come impedire di generare il nome due volte". – Lucky

0

Perché non usare

$filename = md5(rand()); 

Questo sarà praticamente unico in ogni caso. E se trovi che lo $filename esiste già, puoi semplicemente chiamarlo di nuovo.

+1

rand() sarà "praticamente" unico, ma $ data. $ Tempo sarà unico. Perché scambiare uno per l'altro, e oltre a questo non affronta la domanda reale. – Lucky

2

lo consiglio memorizzare il nome del file nella sessione (come da AI). Se lo memorizzi in una delle altre variabili, è più probabile che l'utente finale possa attaccare il sistema attraverso di essa. MD5 dell'utente concatenato con rand() sarebbe un buon modo per ottenere una lunga lista di valori unici. Usare semplicemente rand() probabilmente avrebbe una percentuale più alta di conflitti.

Non sono sicuro del processo che si sta seguendo per il caricamento dei file, ma un altro modo per gestire i caricamenti di file è con i gestori incorporati di PHP. Puoi caricare il file e quindi utilizzare i metodi "sicuri" per estrarre i file caricati dallo spazio temporaneo. (lo spazio temporaneo in questo caso può essere collocato in modo sicuro all'esterno della direttiva dir della base aperta per evitare manomissioni). is_uploaded_file() e move_uploaded_file() da: http://php.net/manual/en/features.file-upload.post-method.php esempio 2 potrebbe gestire il problema che si sta verificando.

Verificare definitivamente la presenza di un file esistente in quella posizione se si sceglie un nome file al volo. Se l'input dell'utente è consentito in qualsiasi forma o forma, convalidare e filtrare l'argomento per assicurarsi che sia sicuro. Inoltre, se la cartella di archiviazione è accessibile dal Web, assicurati di digitarne il nome e probabilmente anche l'estensione. Non vuoi che qualcuno sia in grado di caricare il codice e quindi essere in grado di eseguirlo. Ciò porta ufficialmente alle attività BAD.

2

Voglio solo aggiungere che php ha una funzione per creare identificatori: uniqid. Puoi anche aggiungere un prefisso all'identificatore con una stringa (data forse?).

Convalidare sempre l'input dell'utente e le intestazioni del server!

0

Non è una buona idea utilizzare l'ID in base al tempo: se si caricano due immagini contemporaneamente, la successiva può sovrascrivere quella precedente. Si dovrebbe guardare a funzioni come uniqid(). Tuttavia, se questo script di upload/ridimensionamento/salvataggio è pensato per essere "single-user", allora questo non è un grosso problema.

Per il problema stesso. Se fossi in te, vorrei solo salvare il nome file calcolato su una variabile, usare la variabile da quel punto. Il calcolo già calcolato è uno spreco di tempo. E quando si caricano immagini veramente grandi o più immagini contemporaneamente, lo script può richiedere anche 20 secondi. Non puoi dipendere dal fatto che realizzerai tutto ciò che vuoi in un secondo.