L'upload de fichiers
Par Damien, mardi 26 avril 2005 à 20:11 :: PHP :: #30 :: rss
L'upload de fichiers en PHP est vraiment très facile. Nous allons voir comment faire.
1- Création du formulaire html
Tout d'abord, il faut créer notre formulaire html, avec un ou plusieurs champ(s) permettant au visiteur de sélectionner un fichier sur sa machine.
Ces champs sont des champs input de type file, vous pouvez en mettre autant que vous voulez sur la page, PHP gère l'envoi multiple depuis la version 3.0.10.
Il faut également spécifier la valeur multipart/form-data dans le type d'encodage des données du formulaire (enctype).
Exemple :
<!-- Formulaire --> <!-- Attention, ne de ne pas oublier le enctype="multipart/form-data" --> <form method="POST" action="notre_script.php" enctype="multipart/form-data"> <!-- Limiter la taille des fichiers à 500Ko --> <input type="hidden" name="MAX_FILE_SIZE" value="500000" /> <legend>Envoi de fichiers</legend> <!-- champs d'envoi de fichier, de type file --> <!-- bouton d'envoi --> </legend> </fieldset> </form>
2- Gérer des fichiers envoyés avec PHP
Lorsque le formulaire est envoyé, les fichiers sont envoyés sur le serveur dans un répertoire temporaire. Une fois ces fichiers envoyés, le script php dans la partie action du formulaire est lancé. Une fois que le script php est terminé, les fichiers envoyés sont supprimés du répertoire temporaire. Il faut donc traiter/copier ces fichiers avant.
Récupérer les informations des fichiers envoyés
Les informations sur les fichiers envoyés sont accessibles depuis le tableau global $_FILES, contenant les informations suivantes :
| Clef | Description |
| name | Nom original du fichier, tel que sur la machine du visiteur. |
| type | Type MIME du fichier, si le navigateur a fourni cette information. Exemple : image/gif. |
| size | Taille, en octets, du fichier envoyé. |
| tmp_name | Chemin du fichier temporaire sur le serveur. |
| error | Code d'erreur associé à l'envoi du fichier (PHP > 4.2.0). |
Donc par exemple $_FILES['photo']['tmp_name'] retourne le chemin du fichier temporaire sur le serveur.
Copier les fichiers
Pour copier les fichiers envoyés dans un autre répertoire rien de plus simple, il suffit d'utiliser la fonction move_uploaded_file(). Vous devez néanmoins également donner les droits d'écriture à PHP sur le répertoire dans lequel vous souhaitez copier les fichiers. Pour cela vous pouvez par exemple utiliser la fonction CHMOD de votre logiciel FTP.
Exemple d'utilisation de move_uploaded_file :
<?php { $dest_dossier = '/home/damien/photos/'; // utilisez également des slashes sous windows : $dest_dossier = 'd:/damien/photos/'; } ?>
NB : N'utilisez pas ce code tel quel, lisez bien le prochain chapitre du tutorial.
3- ... mais attention !
Sécurité
Dans l'exemple précédent, le visiteur peut envoyer n'importe quel type de fichier. Rien ne l'empêche d'envoyer un fichier PHP à la place d'une photo ! Et ensuite de l'éxecuter si le répertoire dans lequel vous stockez vos fichiers est accessible depuis le web. Il faut donc toujours penser à vérifier quel type de fichier l'utilisateur envoie, en acceptant que les fichiers ayant l'extension attendue.
<?php // récupère la partie de la chaine à partir du dernier . // Ex : .png // récupère la partie après le . // Ex : png ?>
De plus, le visiteur peut aussi enregistrer le formulaire sur son ordinateur, et modifier la valeur du champ caché MAX_FILE_SIZE, pour ainsi envoyer des fichiers plus volumineux. Il est donc également préférable de vérifier la taille du fichier.
<?php // récupère la taille du fichier ?>
Nom du fichier
Toujours dans l'exemple du chapitre précédent, on utilise le nom original de l'image (tel que sur la machine du visiteur) comme nom du fichier sur notre serveur. Cela peut poser des problèmes. Il est préférable de supprimer les accents, les espaces et les caractères spéciaux.
<?php // enlever les accents 'ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ', 'AAAAAACEEEEIIIIOOOOOUUUUYaaaaaaceeeeiiiioooooouuuuyy'); // remplacer les caracteres autres que lettres, chiffres et point par _ ?>
4- Exemple
L'exemple du chapitre 2 donne donc :
<?php { // params $taille_max = 100000; $dest_dossier = '/home/damien/photos/'; // utilisez également des slashes sous windows : $dest_dossier = 'd:/damien/photos/'; // vérifications { $erreur = 'Veuillez sélectionner un fichier de type png, gif ou jpg !'; } { $erreur = 'Votre fichier doit faire moins de 500Ko !'; } // copie du fichier { // formatage nom fichier // enlever les accents 'ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ', 'AAAAAACEEEEIIIIOOOOOUUUUYaaaaaaceeeeiiiioooooouuuuyy'); // remplacer les caracteres autres que lettres, chiffres et point par _ // copie du fichier } } ?> <html> <body> <!-- Erreur ? --> <?php } ?> <!-- Formulaire --> <!-- Attention, ne de ne pas oublier le enctype="multipart/form-data" --> <form method="POST" action="30.php" enctype="multipart/form-data"> <!-- Limiter la taille des fichiers à 500Ko --> <input type="hidden" name="MAX_FILE_SIZE" value="500000" /> <fieldset> <legend>Envoi de fichiers</legend> <!-- champs d'envoi de fichier, de type file --> <p><label for="photo">Photo :</label><input type="file" name="photo" /></p> <!-- bouton d'envoi --> <p><input type="submit" name="envoi" value="Envoyer les fichiers" /></p> </legend> </fieldset> </form> </body> </html>
Deux autres tutoriaux, avec des exemples plus complets (comment gérer l'envoi d'images, et un autre sur l'importation de fichier CSV) seront mis en ligne prochainement.
5- Remarques complémentaires
Envoyer des fichiers volumineux
Vous avez vu tout à l'heure que l'on peut limiter la taille des fichiers envoyés avec un champ de type hidden. Mais il existe également des options de configuration de la taille maximum dans le fichier php.ini.
- La principale option est la directive upload_max_filesize, qui permet de fixer la taille maximale d'un fichier que l'on peut envoyer (en général 2Mo par défaut).
- Mais augmenter cette valeur peut ne pas être suffisant. Il existe également la directive post_max_size pour délimiter la taille maximum des données qui peuvent être envoyées par la méthode POST (généralement 8Mo par défaut), taille des fichiers envoyés inclue. Pensez donc à modifier les deux valeurs si vous voulez permettre l'upload de fichiers volumineux.
- La directive memory_limit, si activée, peut également avoir une influence sur l'upload de fichier.
- Enfin, il faudra probablement augmenter la limite du temps d'execution de vos scripts à l'aide des directives max_execution_time et max_input_time.
Seules les directives memory_limit et max_*_time sont modifiables depuis vos scripts php :
<?php ?>
Pour modifier les deux autres options (si vous n'avez pas accès aux fichiers php.ini ou httpd.conf), vous devez utiliser un fichier .htaccess :
php_value upload_max_filesize 5000000 php_value post_max_size 10000000
NB : Attention, pour modifier la configuration de PHP depuis un fichier .htaccess, PHP doit être installé en tant que module apache, pas en tant que CGI. Vous obtenez sinon une erreur 500.
Afficher la progression du téléchargement
Malheureusement, PHP ne permet pas d'afficher de barre de progression pendant le téléchargement. Pourquoi ? La raison est simple, le script PHP est appelé uniquement lorsque l'envoi du fichier est terminé, et ne donne pas accès aux données raw post. On ne peut donc pas controler où en est le chargement, même en utilisant du javascript.
Pas sans changement en tous cas. Il existe en effet une extension non officielle qui permet de gérer une barre de progression pendant le téléchargement. Il faut par contre appliquer un patch à PHP, et compiler l'extension. Vous ne pouvez pas le faire n'importe où (il faut pouvoir administrer le serveur), et vous devez avoir les compétences pour le faire. Le lien ci dessous n'est donc fournit qu'à titre informatif, et s'adresse aux utilisateurs avancés. A vos risques et périls.
- Upload progress meter
- Démonstration (prévenez-moi si le lien n'est plus à jour)
Sinon, il existe également un projet utilisant un mix de PHP et de Perl, ne nécessitant pas d'appliquer de patch au serveur. Vous devez néanmoins pouvoir utiliser Perl sur votre serveur, bien évidemment.
- Mega upload (site officiel)
- Mega upload (sourceforge)
- Démonstration (prévenez-moi si le lien n'est plus à jour)
6- Autres ressources
- Tutorial de Flood, dans la FAQ des forums PHPFrance

Commentaires
1. Le samedi 30 avril 2005 à 18:39, par Pouille
2. Le vendredi 6 mai 2005 à 10:26, par Nono
3. Le vendredi 13 mai 2005 à 16:14, par emap
4. Le vendredi 13 mai 2005 à 22:14, par TMS
5. Le lundi 16 mai 2005 à 21:46, par sugar
6. Le mardi 17 mai 2005 à 17:02, par Thia
7. Le lundi 23 mai 2005 à 14:57, par BaO
8. Le mercredi 25 mai 2005 à 23:24, par eugene16
9. Le lundi 30 mai 2005 à 11:32, par bad boy
10. Le jeudi 2 juin 2005 à 14:30, par eisbaer
11. Le vendredi 10 juin 2005 à 11:13, par toinou
12. Le samedi 18 juin 2005 à 09:06, par Furious
13. Le lundi 27 juin 2005 à 11:46, par lolo
14. Le mercredi 29 juin 2005 à 12:11, par densoues
15. Le mercredi 13 juillet 2005 à 10:25, par bigflooow
16. Le samedi 23 juillet 2005 à 18:31, par Juliian
17. Le mercredi 17 août 2005 à 15:22, par Mike
18. Le mardi 23 août 2005 à 15:29, par wildphoenix
19. Le jeudi 25 août 2005 à 00:27, par Crocozor
20. Le jeudi 25 août 2005 à 00:50, par Crocozor
21. Le mercredi 7 septembre 2005 à 15:15, par nanarou
22. Le jeudi 15 septembre 2005 à 20:12, par fridim
23. Le mercredi 21 septembre 2005 à 17:27, par Julien
24. Le vendredi 23 septembre 2005 à 23:01, par naha
25. Le samedi 24 septembre 2005 à 01:50, par Coolrastaboy
26. Le lundi 26 septembre 2005 à 20:04, par naha
27. Le mardi 27 septembre 2005 à 15:38, par Erazer
28. Le lundi 17 octobre 2005 à 14:25, par toome
29. Le mardi 18 octobre 2005 à 11:38, par toome
30. Le samedi 22 octobre 2005 à 22:36, par fifal
31. Le jeudi 27 octobre 2005 à 19:58, par jibouze
32. Le samedi 19 novembre 2005 à 11:15, par Cowboy
33. Le lundi 21 novembre 2005 à 18:28, par Aramas
34. Le lundi 21 novembre 2005 à 18:46, par Aramas
35. Le samedi 26 novembre 2005 à 19:22, par filomat
36. Le jeudi 1 décembre 2005 à 16:27, par philoult
37. Le lundi 19 décembre 2005 à 13:41, par Juki
38. Le jeudi 22 décembre 2005 à 17:49, par etto
39. Le jeudi 22 décembre 2005 à 23:14, par lanner
40. Le jeudi 22 décembre 2005 à 23:39, par ett
41. Le dimanche 25 décembre 2005 à 20:01, par skaPiX
42. Le mercredi 28 décembre 2005 à 20:58, par youkizedog
43. Le jeudi 29 décembre 2005 à 14:51, par Hellraiser
44. Le jeudi 5 janvier 2006 à 16:35, par jeanclement
45. Le vendredi 6 janvier 2006 à 19:00, par facilitant
46. Le vendredi 6 janvier 2006 à 19:32, par facilitant
47. Le lundi 9 janvier 2006 à 17:39, par zibotaz
48. Le mercredi 11 janvier 2006 à 14:59, par Olivier
49. Le vendredi 20 janvier 2006 à 16:50, par Tifrito
50. Le vendredi 20 janvier 2006 à 16:52, par Tifrito
51. Le dimanche 5 février 2006 à 12:52, par Superbouba86
52. Le dimanche 5 février 2006 à 17:08, par Damien
53. Le lundi 13 février 2006 à 20:29, par vincent
54. Le mercredi 15 février 2006 à 08:33, par pako
55. Le vendredi 17 février 2006 à 04:47, par Timale
56. Le vendredi 17 février 2006 à 14:58, par Suprateam
57. Le mercredi 22 février 2006 à 18:43, par Redman
58. Le dimanche 26 février 2006 à 14:48, par domikou
59. Le jeudi 2 mars 2006 à 19:51, par dod
60. Le lundi 6 mars 2006 à 16:16, par clem
61. Le mercredi 8 mars 2006 à 07:37, par dalep
62. Le mercredi 8 mars 2006 à 18:02, par richard bruandet
63. Le dimanche 12 mars 2006 à 18:37, par Vladst
64. Le mardi 14 mars 2006 à 15:06, par vite fait
65. Le mardi 14 mars 2006 à 21:35, par yano
66. Le lundi 27 mars 2006 à 16:51, par Debutant88
67. Le mardi 28 mars 2006 à 15:52, par Chachoo
68. Le vendredi 31 mars 2006 à 16:26, par Viper82
69. Le samedi 15 avril 2006 à 09:34, par tilillois
70. Le samedi 6 mai 2006 à 23:58, par Sergent PanPan
71. Le dimanche 7 mai 2006 à 03:09, par alesq
72. Le lundi 8 mai 2006 à 17:15, par fanch
73. Le mercredi 10 mai 2006 à 15:33, par kishins
74. Le jeudi 11 mai 2006 à 11:04, par speedylol
75. Le jeudi 11 mai 2006 à 15:33, par zeibud
76. Le jeudi 11 mai 2006 à 20:01, par Final Second Weekend Getaway
77. Le mardi 16 mai 2006 à 17:37, par Aude
78. Le mercredi 17 mai 2006 à 11:33, par Aude
79. Le samedi 20 mai 2006 à 19:13, par Mawashigeri
80. Le mardi 30 mai 2006 à 19:39, par artotal
81. Le lundi 5 juin 2006 à 18:14, par thierry8
82. Le mardi 6 juin 2006 à 00:44, par quent.
83. Le mercredi 7 juin 2006 à 14:51, par nv
84. Le jeudi 15 juin 2006 à 23:53, par eric
85. Le jeudi 15 juin 2006 à 23:53, par eric
86. Le lundi 19 juin 2006 à 16:31, par verogflip
87. Le lundi 19 juin 2006 à 16:32, par verogflip
88. Le vendredi 23 juin 2006 à 19:21, par Toshiba A10
89. Le mercredi 28 juin 2006 à 15:34, par David
90. Le vendredi 30 juin 2006 à 15:21, par Spy911
91. Le lundi 17 juillet 2006 à 14:36, par Robin
92. Le mercredi 16 août 2006 à 11:48, par Nik
93. Le mercredi 23 août 2006 à 18:12, par alain59
94. Le samedi 26 août 2006 à 15:09, par amir
95. Le samedi 26 août 2006 à 23:29, par droopy
96. Le samedi 2 septembre 2006 à 19:10, par lulululu
97. Le samedi 2 septembre 2006 à 19:25, par lutinfou
98. Le mardi 5 septembre 2006 à 21:11, par ullysse
99. Le samedi 9 septembre 2006 à 15:23, par JLN
100. Le dimanche 10 septembre 2006 à 19:24, par DEF_side
101. Le mardi 10 octobre 2006 à 11:46, par Bumblebee
102. Le mercredi 11 octobre 2006 à 09:26, par pampi
103. Le mardi 17 octobre 2006 à 11:19, par Lezard
104. Le jeudi 19 octobre 2006 à 22:18, par Jerry Wham
105. Le mardi 24 octobre 2006 à 10:05, par help_phpfrance
106. Le mardi 24 octobre 2006 à 10:18, par help_phpfrance
107. Le mercredi 8 novembre 2006 à 10:54, par GanHalf
108. Le mardi 14 novembre 2006 à 16:03, par Gloubie
109. Le lundi 20 novembre 2006 à 10:15, par vopicek
110. Le dimanche 10 décembre 2006 à 18:06, par mIGI
111. Le lundi 5 février 2007 à 19:18, par icom7
112. Le jeudi 8 février 2007 à 16:36, par didou
113. Le mardi 6 mars 2007 à 20:52, par Bernard_Québec
114. Le vendredi 23 mars 2007 à 14:56, par Grenouille
115. Le mercredi 11 avril 2007 à 23:22, par Anderson
116. Le samedi 21 avril 2007 à 01:03, par Hindioumax
117. Le mercredi 9 mai 2007 à 21:25, par fuchie
118. Le samedi 19 mai 2007 à 14:17, par Développement Solutions internet
119. Le mercredi 23 mai 2007 à 17:27, par mattam
120. Le mercredi 23 mai 2007 à 17:29, par Mathieu
121. Le mardi 26 juin 2007 à 10:15, par med
122. Le vendredi 20 juillet 2007 à 22:44, par Ben_amir
123. Le vendredi 20 juillet 2007 à 23:05, par Ben_Amir
124. Le dimanche 22 juillet 2007 à 00:25, par XXXKNOXXX
125. Le mercredi 8 août 2007 à 23:46, par marie
126. Le lundi 20 août 2007 à 20:19, par lolo17
127. Le lundi 3 septembre 2007 à 23:34, par playjudoboy
128. Le mercredi 19 septembre 2007 à 15:51, par JavaForLife
129. Le mercredi 19 septembre 2007 à 15:56, par JavaForLife
130. Le samedi 13 octobre 2007 à 18:07, par krma777
131. Le lundi 12 novembre 2007 à 01:14, par ChrissieD
132. Le jeudi 29 novembre 2007 à 11:14, par None
133. Le dimanche 23 décembre 2007 à 16:16, par hood
134. Le vendredi 4 janvier 2008 à 20:31, par Eric
135. Le samedi 5 janvier 2008 à 00:41, par test qi
136. Le samedi 19 janvier 2008 à 12:27, par algerino-fez
137. Le dimanche 27 janvier 2008 à 12:42, par ahcene
138. Le dimanche 9 mars 2008 à 21:00, par saturn1
139. Le jeudi 13 mars 2008 à 15:58, par Eric
140. Le samedi 12 avril 2008 à 00:32, par Luffy
141. Le jeudi 24 avril 2008 à 18:31, par hermious
142. Le dimanche 8 juin 2008 à 02:00, par hermes
143. Le dimanche 8 juin 2008 à 04:08, par LynX
144. Le lundi 23 juin 2008 à 00:35, par ArkAnge
Ajouter un commentaire
Les commentaires pour ce billet sont fermés.