Création d'un nom de fichier unique en fonction du temps pour le téléchargement sans créer une condition de course

StackOverflow https://stackoverflow.com/questions/1261805

  •  12-09-2019
  •  | 
  •  

Question

Je suis générer un nom de fichier unique pour les fichiers téléchargés avec le code suivant

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

Le problème est que je veux utiliser ce nom de fichier à nouveau plus tard dans le script, mais si le script prend une seconde pour courir, je vais avoir un nom différent la deuxième fois que j'essaie d'utiliser cette variable.

Par exemple, j'utilise un téléchargement / redimensionner / enregistrer script d'upload d'image. La première opération du script est de copier et enregistrer l'image redimensionnée, que j'utilise une fonction de la date d'attribuer un nom unique à. Ensuite, le script processses la sauvegarde et enregistre le tout téléchargement, et lui attribue un nom. A la fin du script ($thumb et $full sont les variables), je dois insérer dans une base de données MySQL, les noms de fichiers que j'ai utilisé quand je les uploads sauvé.

Le problème est, parfois sur de grandes images, il faut plus d'une seconde (ou au cours du processus, les secondes changent) résultant en un nom différent d'être mis dans la base de données que est ce que le fichier est en fait enregistré sous.

Est-ce tout simplement pas une bonne idée d'utiliser cette méthode de nommer?

Était-ce utile?

La solution

il est AFAIK une excellente façon de nommer les fichiers, bien que je vérifierais file_exists() et peut-être virer de bord sur un nombre aléatoire.

Vous devez stocker ce nom de fichier dans une variable et référencer plus tard, au lieu de compter sur l'algorithme à chaque fois. Cela pourrait être stocké dans le $_SESSION utilisateur, un cookie, une variable GET, etc entre pageloads.

L'espoir qui aide

Autres conseils

Je veux juste ajouter que php a une fonction pour créer des identifiants: uniqid. Vous pouvez également le préfixe de l'identifiant avec une chaîne (date peut-être?).

Toujours valider l'entrée de votre utilisateur et les en-têtes de serveur!

Je recommande de conserver le nom de fichier dans la session (selon AI). Si vous stockez dans l'une des autres variables, il est plus probable pour l'utilisateur final pour pouvoir attaquer le système à travers elle. MD5 de l'utilisateur concaténé avec rand () serait un bon moyen d'obtenir une longue liste de valeurs uniques. Juste en utilisant rand () aurait probablement un pourcentage plus élevé de conflits.

Je ne suis pas sûr au sujet du processus que vous suivez pour le téléchargement de fichiers, mais une autre façon de gérer le téléchargement de fichiers est avec PHP construit dans les gestionnaires. Vous pouvez télécharger le fichier, puis utiliser les méthodes « sûres » pour tirer les fichiers téléchargés sur l'espace temporaire. (L'espace temporaire dans ce cas peut être situé à l'extérieur en toute sécurité de la directive de base dir ouverte pour empêcher toute manipulation). is_uploaded_file () et move_uploaded_file () à partir de: http: // php .net / manuel / fr / features.file-upload.post-method.php exemple 2 peut gérer le problème que vous rencontrez.

Certainement vérifier un fichier existant à cet endroit si vous choisissez un nom de fichier à la volée. Si l'entrée d'utilisateur est autorisé sous une forme quelconque manière que ce soit, de valider et de filtrer l'argument pour vous assurer qu'il est sûr. En outre, si le dossier de stockage est accessible sur le Web, assurez-vous Munge le nom et probablement l'extension ainsi. Vous ne voulez pas que quelqu'un soit en mesure de télécharger le code et être en mesure de l'exécuter. Cela conduit officiellement aux activités BAD.

Je viens de découvrir que PHP a une fonction intégrée pour cela, appelé tempnam. Il évite même les conditions de course. Voir http://php.net/manual/en/function.tempnam.php.

Pourquoi ne pas utiliser

$filename = md5(rand());

Ce sera à peu près unique dans tous les cas. Et si vous trouvez que $filename existe déjà, vous pouvez simplement l'appeler à nouveau.

Pas une bonne idée en utilisant ID en fonction du temps - si vous téléchargez deux images en même temps, celui qui plus tard peut remplacer le plus tôt. Vous devriez regarder fonction comme uniqid () . Toutefois, si ce script upload / redimensionne / save est censé être « mono-utilisateur », alors ce n'est pas un gros problème.

Pour le problème lui-même. Si je devais vous, je voudrais juste enregistrer le nom de fichier calculé à une variable d'une utilisation la variable de ce point. Informatique déjà calculé est perte de temps. Et lors du téléchargement des images vraiment grand, ou plus d'images à la fois, le script peut prendre même 20 secondes. Vous ne pouvez pas dépendre de fait que vous tout ce que vous voulez faire en une seconde.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top