Tom's Guide > Forum > Programmation > [Résolu] [PHP] renommer un fichier si il existe déja

[Résolu] [PHP] renommer un fichier si il existe déja

Forum Programmation : [Résolu] [PHP] renommer un fichier si il existe déja

TomsGuide.com : 800 000 inscrits répondent à toutes vos questions high-tech et informatique. Pour obtenir de l'aide, inscrivez-vous gratuitement !
Mot :    Pseudo :           
 

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
Liens sponsorisés
Inscrivez-vous ou connectez-vous pour masquer ceci.

Bien entendu, tu ne peux pas faire un rename alors que le fichier n'est pas encore copié.
Tu devrais plutôt faire:

Code :
  1. if (file_exists("/upload/$nom_fichier" )) {
  2.   $nom_fichier = $rand."_".$nomfichier;
  3. }


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.

Répondre à crazycat@idn

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
Répondre à coca25

Donc mon

Code :
  1. if (file_exists("/upload/$nom_fichier" )) {
  2. $nom_fichier = $rand."_".$nomfichier;
  3. }



Je le met ou ?

c'est pas pour renommer l'ancien, mais celui qu'on cherche a uploader !

Répondre à Jeoffrey54

tu le met à la place de ton:

Code :
  1. if (file_exists($filename)) {
  2.   rename("/upload/$nom_fichier", "/upload/$nom_fichier$rand" );
  3. } else {
  4. }


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...

Répondre à crazycat@idn

Ca ne marche pas :(

J'ai mis a jour le fichier upload.txt

Répondre à Jeoffrey54

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 :
  1. $rand = 'rand(5, 50)';


depuis quand on met des ' ' autour d'un appel de fonction?

Répondre à crazycat@idn

Il ne veut toujours pas me modifier le fichier que je tente d'uploader uen deuxieme fois !

Acutellement j'ai ca :

Code :
  1. $rand = rand(5, 50);
  2. if (file_exists("/upload/$nom_fichier" )) {
  3. $nom_fichier = $rand."_".$nomfichier;
  4. }



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é.

Répondre à Jeoffrey54

dans la meme optique:

Code :
  1. $filename = '/upload/$nom_fichier';


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
Répondre à coca25

Jeoffrey54 a écrit :

Acutellement j'ai ca :

Code :
  1. $rand = rand(5, 50);
  2. if (file_exists("/upload/$nom_fichier" )) {
  3. $nom_fichier = $rand."_".$nomfichier;
  4. }




Tu pourrais AU MOINS corriger mes fautes de frappe.
$nom_fichier = $rand."_".$nomfichier; <-- plutôt $nom_fichier

Répondre à crazycat@idn

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 :
  1. $rand = rand(5, 50);
  2. if (file_exists("/upload/$nom_fichier" )) {
  3. $nom_fichier = $rand."_".$nom_fichier;
  4. }



Mais pas moyen d'ajouter ces nombre au début :(

Répondre à Jeoffrey54

fais des affichages de debug pour savoir ce qui échoue.
Et je te signale une petite erreur en passant:

Code :
  1. copy($ftmp,"upload/".$nom_fichier);


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.

Répondre à crazycat@idn

Mon site est a la racine, donc aucun problème, mais sinon c'est quoi les affichages de debug ?

Répondre à Jeoffrey54

par exemple:

Code :
  1. if (file_exists("/upload/$nom_fichier" )) {
  2.   echo "-- On a déjà le fichier ".$nom_fichier." --<br />\n";
  3.   $rand = rand(5, 50);
  4.   echo "-- On a créé le préfixe ".$rand." --<br />\n";
  5.   $nom_fichier = $rand."_".$nom_fichier;
  6.   echo "-- Le nouveau nom de fichier est ".$nom_fichier." --<br />\n";
  7. }


Tu noteras que j'ai passé le rand() dans le if pour éviter de générer inutilement la variable.

Répondre à crazycat@idn

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.

Répondre à coca25

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.

Répondre à crazycat@idn

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
Répondre à coca25

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).

Répondre à crazycat@idn

Regarde le fichier texte à cette adresse

J'ai noté aucune amélioration, ca n'affiche pas les echo que tu a mis.

Code :
  1. if (file_exists("/upload/$nom_fichier" )) {
  2. echo "-- On a déjà le fichier ".$nom_fichier." --<br />\n";
  3. $rand = rand(5, 50);
  4. echo "-- On a créé le préfixe ".$rand." --<br />\n";
  5. $nom_fichier = $rand."_".$nom_fichier;
  6. echo "-- Le nouveau nom de fichier est ".$nom_fichier." --<br />\n";
  7. }

Répondre à Jeoffrey54

dans ce cas, c'est que tu ne rentres pas dans ton if.
Conclusion: vire le / initial devant tout tes "upload".

Répondre à crazycat@idn

Crazycat, je t'aime ! (l)

J'ai supprimé les / devant upload et ca marche ;)

Encore merci :D

Répondre à Jeoffrey54

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 :
  1. $rand = uniqid(rand());

Répondre à crazycat@idn

quel est la différence ?

Répondre à Jeoffrey54

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"...

Répondre à crazycat@idn

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 :
  1. safe_mode = On
  2. doc_root = "/var/www/html/php"
  3. user_dir = "public_php"



j'ai raté quelque chose?


Message édité par coca25 le 12-02-2007 à 17:57:12
Répondre à coca25

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).

Répondre à crazycat@idn

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 ;)

Répondre à coca25

moi je renomme avec l'id de la photo up (enregistre dans mysql) en md5 ou, avec la date entiere :


yyyymmddHis

ou

time()

Répondre à okinou

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 :
yyyymmddHis


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é.

Répondre à crazycat@idn

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.

Répondre à okinou

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.

Répondre à crazycat@idn

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 ?

Répondre à Jeoffrey54

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
Répondre à coca25

Ok, mais tu trouves pas que ca fait grand comme nom ?

Répondre à Jeoffrey54

c'etait une solution possible
à toi de voir ce qui te convient

Répondre à coca25

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é ;)

Répondre à Jeoffrey54

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éseau IRC Francophone | g33k-zone
Répondre à crazycat@idn

tout à fait, pour aucune enmerde, utilise sha1 md5 ou les date.

Répondre à okinou

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 ?

Répondre à Jeoffrey54

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
Répondre à okinou

C'est bon calme toi !

Problème résolu, merci et @+

Répondre à Jeoffrey54

Je suis calme, cool, zen, exomile...


Message édité par okinou le 13-02-2007 à 10:53:55
Répondre à okinou

au moins ca a le mérite d'être clair :D
pour le résolu, c'est dans le titre qu'on le place

Répondre à coca25
Tom's Guide > Forum > Programmation > [Résolu] [PHP] renommer un fichier si il existe déja
Aller à :

Il y a 447 utilisateurs connus et inconnus. Pour voir la liste des connectés connus, cliquez ici.

Attention

Vous allez répondre sur un sujet resté inactif pendant plus de 6 mois.
Assurez-vous d'apporter des éléments nouveaux à la discussion avant de poursuivre.

Répondre Annuler
Liens