[Résolu] [PHP] renommer un fichier si il existe déja
Forum Programmation : [Résolu] [PHP] renommer un fichier si il existe déja
Hello, je viens de faire un uploader d'images, disponible a cetet adresse.
Mais j'aimerais mettre en place un code qui renomme l'image si celle ci existe déja dans le répértoire d'upload. Exemple, si j'uplaode salut.png et que je le réuploade une deuxieme fois, j'aurais salut154.png.
Pour cela j'ai mis en place ceci :
$filename = '/upload/$nom_fichier';
$rand = 'rand(5, 50)';
if (file_exists($filename)) {
rename("/upload/$nom_fichier", "/upload/$nom_fichier$rand" );
} else {
}
Mais marche pas
le code source est disponible a cetet adresse
J'espère que vous pourrez m'aider.
Bonne journée
Message édité par Jeoffrey54 le 13-02-2007 à 12:17:56
Bien entendu, tu ne peux pas faire un rename alors que le fichier n'est pas encore copié.
Tu devrais plutôt faire:
Code :
|
D'ailleurs, je passe ton $rand avant pour ne pas te faire perdre l'extension.
Et un petit truc utile: lorsqu'on fait un système d'upload de fichiers destinés à être archivés, il est intéressant de TOUJOURS ajouter un identifiant unique, soit en utilisant uniqid() soit en faisant précéder le nom de (par exemple) date("YmdHis_" ).
Cela t'évite d'avoir à vérifier chaque fois si le fichier existe déjà, d'autant plus que le rand() peut te renvoyer plusieurs fois la même valeur.
si je comprends bien, tu veux renommer l'ancien puis copier le nouveau?
si c'est le cas, faudrait enlever le else
EDIT:
| crazycat@idn a écrit : Bien entendu, tu ne peux pas faire un rename alors que le fichier n'est pas encore copié |
si file_exists () retourne vrai, il peut, mais il va renommer l'ancien
enfin ca depend de ce qu'il a voulu faire
Message édité par coca25 le 12-02-2007 à 14:34:48
Donc mon
Code :
|
Je le met ou ?
c'est pas pour renommer l'ancien, mais celui qu'on cherche a uploader !
tu le met à la place de ton:
Code :
|
En fait, ça permet de changer le nom de destination *avant* la copie du fichier temp vers sa place définitive.
Je présume que le script initial n'est pas de toi...
Ca ne marche pas
J'ai mis a jour le fichier upload.txt
tout d'abord, "ça ne marche pas" n'est pas constructif.
Ensuite, tu devrais plutôt utiliser la fonction dédiée au déplacement de fichiers uploadés (move_uploaded_file()) plutôt que copy().
Et tu as une erreur (que je n'avais pas relevée):
Code :
|
depuis quand on met des ' ' autour d'un appel de fonction?
Il ne veut toujours pas me modifier le fichier que je tente d'uploader uen deuxieme fois !
Acutellement j'ai ca :
Code :
|
J'ai msi a jour le fichier texte pour avoir une vue d'ensemble.
Pour le move_uploaded_file, je le mettrais surement lorsque mon problème sera réglé.
dans la meme optique:
Code :
|
une variable entre ' ' n'est pas intérprétée, mais j'ai vu que ce n'etait pas pareil sur le upload.txt
EDIT:
d'ailleurs rand n'est pas affectée dans upload.txt à part si c'est le cas dans le include du menu
Message édité par coca25 le 12-02-2007 à 15:31:07
| Jeoffrey54 a écrit : Acutellement j'ai ca :
|
Tu pourrais AU MOINS corriger mes fautes de frappe.
$nom_fichier = $rand."_".$nomfichier; <-- plutôt $nom_fichier
Arf, j'ai été un peu trop vite. Bon jviens de revoir un peu tout ca, j'ai regardé un peu les variables, j'ai ca pour l'instant :
Code :
|
Mais pas moyen d'ajouter ces nombre au début
fais des affichages de debug pour savoir ce qui échoue.
Et je te signale une petite erreur en passant:
Code :
|
Un peu partout, tu utilises le répertoire /upload (donc à la racine de ton site) et là tu utilises un sous-répertoire du répertoire courant.
Donc, si ton script n'est pas à la racine de ton site, tu n'up pas dans le bon répertoire.
Mon site est a la racine, donc aucun problème, mais sinon c'est quoi les affichages de debug ?
par exemple:
Code :
|
Tu noteras que j'ai passé le rand() dans le if pour éviter de générer inutilement la variable.
il y a une difference qd meme, a part si ton site est à la racine de ton disque, parce qu'en l'occurence, le chemin ( et donc le "/" ) dans file_exists et cie s'applique à l'arboressence du disque et non du site.
NON! Du moins pas toujours.
le / s'applique très souvent au document_root et non pas au root de la machine (si la configuration est bien faite).
Mais il est vrai qu'il vaut mieux utiliser un chemin relatif ou un chemin physique réel.
ah, si c'est une question de config, je connaissais pas, et du coup, si on veut acceder à un rep en dehors du site, ca se passe comment?
EDIT: sur une config standard, ca a l'air d'etre la racine du disque...
si tu connais l'element de config pour rendre / = racine du site, je suis interessé
Message édité par coca25 le 12-02-2007 à 17:09:53
tout est affaire de configuration, je te conseille de jeter un oeil sur les variables de php.ini:
http://fr.php.net/manual/fr/ini.co [...] clude-path ainsi que les 2 suivantes (doc_root et user_dir).
Et à moins d'être sur un serveur qu'on maitrise parfaitement (un dédié), il est impossible d'accéder à un répertoire qui n'appartient pas à son espace web (ou espace personnel, selon la configuration).
Regarde le fichier texte à cette adresse
J'ai noté aucune amélioration, ca n'affiche pas les echo que tu a mis.
Code :
|
dans ce cas, c'est que tu ne rentres pas dans ton if.
Conclusion: vire le / initial devant tout tes "upload".
Crazycat, je t'aime ! (l)
J'ai supprimé les / devant upload et ca marche
Encore merci
C'est une rêgle quasi vitale à connaitre: toujours adopter la même convention d'écriture pour les chemins des fichiers.
Et encore une fois, je t'invite à utiliser autre chose que le rand() pour préfixer tes fichiers, comme:
Code :
|
quel est la différence ?
tout est dit dans la doc
rand() génère un nombre "aléatoire" entre 0 et 1. Dans ton cas (rand(5,50)), il va générer un nombre au hazard entre 5 et 50, ce qui veut dire que tu pourras au maximum avoir 45 images du même nom.
De plus, rien n'interdit à rand() de sortir plusieurs fois le même chiffre, et tu ne fais qu'une seule vérification, donc à terme tes probabilités d'écraser un fichier déjà existant sont assez énormes*.
uniqid() génère un nombre de 13 chiffres basé sur microtime() (les millisecondes système) et le préfixe donné (dans notre cas, rand()).
Les probabilités d'avoir deux fois le même uniqid de généré sont donc beaucoup plus faibles.
* Si tu savais le nombre de personnes qui vont envoyer un fichier appelé "logo.png", "avatar.gif" ou "moi.jpg"...
je m'incruste avec mes questions mais crazy, effectivement j'avais jamais utilisé ces directives et comme je suis curieux
je les ai téstées.
ca ne m'a pas rendu le / = racine du site, par contre ca m'empeche d'aller lire un fichier en dehors du repertoire que j'ai indiqué
ex:
Code :
|
j'ai raté quelque chose?
Message édité par coca25 le 12-02-2007 à 17:57:12
C'est le safe_mode qui te bloque.
Concernant le / qui représenterait la racine du site, je crois avoir fait une petite erreur (par omission): c'est la config d'apache qui permet cela.
Maintenant, je ne peux pas t'en dire plus car c'est quelque chose que j'ai rencontré sur le serveur d'un client (je me suis cassé les dents dessus pendant des heures) et je n'ai jamais tenté de le reproduire car c'est très chiatique à gérer (en temps que webmaster).
le safe_mode etait volontaire
c'etait le / que je comprenais pas, effectivement je crois que php bloque l'acces, mais ne reaffecte pas le /
je connaissais pas doc_root, c'est toujours bon à savoir
moi je renomme avec l'id de la photo up (enregistre dans mysql) en md5 ou, avec la date entiere :
yyyymmddHis
ou
time()
| crazycat@idn a écrit : soit en utilisant uniqid() soit en faisant précéder le nom de (par exemple) date("YmdHis_" ).
|
| okinou a écrit : moi je renomme avec l'id de la photo up (enregistre dans mysql) en md5 ou, avec la date entiere :
|
le md5() n'est pas bijectif, tu peux avoir 2 md5 identiques pour des chaines différentes.
La date est à priori unique et en plus elle permet un tri aisé.
je n'avais pas tout lu, la fleem, j'exposais ma méthode
pour le md5, peut etre si tu as des millions de photos, mais pour un usage personnel, sachant qu'une chaine aura 32 caractere, pour l'espoir de retombé avec la meme clé est quasi impossible.
Oui, bien sûr, je parle dans l'absolu.
En règle générale et pour un usage limité, on peut très bien utiliser md5 et sha1.
L'avantage de la méthode par date/heure est un classement simplifié et logique.
J'ai essayé avec $rand = uniqid(rand());
et il m'a donné le préfixe 66346640745d0b36483953.
Ca fait un peu beaucoup non ? Comment le réduire ?
si tu le reduis, tu perds son caractere unique
si ca te parait bcp, utilise l'heure comme indiqué plus haut
Message édité par coca25 le 12-02-2007 à 20:05:20
Ok, mais tu trouves pas que ca fait grand comme nom ?
c'etait une solution possible
à toi de voir ce qui te convient
J'ai mis $rand = rand(5, 1000);
J'ai plus de 900 possibilités, et puis ce n'est qu'un site perso, j'utiliserai uniqid(rand()); si je m'aperçois que mon uploader est beaucoup utilisé
le problème reste le même: rand() ne t'assure pas que tu auras un identifiant jamais utilisé.
Rien n'empèche que le même chiffre sorte 3 fois sur 10 tirages.
Répondre à crazycat@idn
tout à fait, pour aucune enmerde, utilise sha1 md5 ou les date.
Je vois ce que tu veux dire Crazycat, je vais remettre uniqid(rand()); mais n'y a t'il pas moyen d'afficher moins de nombres ? Car 66346640745d0b36483953 ca fait beaucoup non ?
ON VIENT DE TE DIRE QUE C'EST NORMAL, comment espère tu avoir une chaine unique si tu n'as que 2 caractère dans ta chaine ?
Ici avec uniqid tu as 22 caractère, md5 en créer 32.
SECONDE SOLUTION, ET DERNIERE FOIS QUE JE ME REPETE, tu utilises la DATE :
date("YmdHis_" )
ce qui te fera :
20070213010534 soit 14 caractere pour l'heure : 13 fevrier 2007 01:05:34 sec
Lis un peut ce que l'on te dit bordel !
Et pour finir, la doc, c'est magique :
http://fr.php.net/manual/fr/function.md5.php
http://fr.php.net/manual/fr/function.uniqid.php
http://fr.php.net/manual/fr/function.date.php
Message édité par okinou le 13-02-2007 à 01:09:19
C'est bon calme toi !
Problème résolu, merci et @+
Je suis calme, cool, zen, exomile...
Message édité par okinou le 13-02-2007 à 10:53:55
au moins ca a le mérite d'être clair
pour le résolu, c'est dans le titre qu'on le place
Il y a 447 utilisateurs connus et inconnus. Pour voir la liste des connectés connus, cliquez ici.

crazycat@idn