Concevez votre site web avec PHP et MySQL

Concevez votre site web avec PHP et MySQL

Mis à jour le lundi 16 juin 2014

Les formulaires constituent le principal moyen pour vos visiteurs d'entrer des informations sur votre site. Les formulaires permettent de créer une interactivité.

Par exemple, sur un forum on doit insérer du texte puis cliquer sur un bouton pour envoyer son message. Sur un livre d'or, sur un mini-chat, on procède de la même façon. On a besoin des formulaires partout pour échanger des informations avec nos visiteurs.

Vous allez voir qu'il y a de nombreux rappels de HTML dans ce chapitre… et ce n'est pas un hasard : ici, le PHP et le HTML sont intimement liés. Le HTML permet de créer le formulaire, tandis que le PHP permet de traiter les informations que le visiteur a entrées dans le formulaire.

Ce chapitre est particulièrement important, nous réutiliserons ce que nous avons appris ici dans toute la suite du cours. Soyez attentifs !

Créer la base du formulaire

En HTML, pour insérer un formulaire, on se sert de la balise <form>. On l'utilise de la manière suivante :

<form method="post" action="cible.php">
 
<p>
    On insèrera ici les éléments de notre formulaire.
</p>
 
</form>

Je souhaite attirer votre attention sur la toute première ligne de ce code. Il y a deux attributs très importants à connaître pour la balise <form> : la méthode (method) et la cible (action). Il est impératif que vous compreniez à quoi ils servent.

La méthode

Il faut savoir qu'il existe plusieurs moyens d'envoyer les données du formulaire (plusieurs « méthodes »). Vous pouvez en employer deux.

  • get : les données transiteront par l'URL comme on l'a appris précédemment. On pourra les récupérer grâce à l'array $_GET. Cette méthode est assez peu utilisée car on ne peut pas envoyer beaucoup d'informations dans l'URL (je vous disais dans le chapitre précédent qu'il était préférable de ne pas dépasser 256 caractères).

  • post : les données ne transiteront pas par l'URL, l'utilisateur ne les verra donc pas passer dans la barre d'adresse. Cette méthode permet d'envoyer autant de données que l'on veut, ce qui fait qu'on la privilégie le plus souvent. Néanmoins, les données ne sont pas plus sécurisées qu'avec la méthode GET et il faudra toujours vérifier si tous les paramètres sont bien présents et valides, comme on l'a fait dans le chapitre précédent. On ne doit pas plus faire confiance aux formulaires qu'aux URL.

C'est à vous de choisir par quelle méthode vous souhaitez que les données du formulaire soient envoyées. Si vous hésitez, sachez que dans 99 % des cas la méthode que l'on utilise est post, vous écrirez donc method="post" comme je l'ai fait.

La cible

L'attribut action sert à définir la page appelée par le formulaire. C'est cette page qui recevra les données du formulaire et qui sera chargée de les traiter.

Imaginons le schéma de la figure suivante.

Appel de la page cible par le formulaire
Appel de la page cible par le formulaire

Dans cet exemple, le formulaire se trouve dans la page formulaire.php. Cette page ne fait aucun traitement particulier, mais une fois le formulaire envoyé (lorsqu'on a cliqué sur le bouton « Valider »), le visiteur est redirigé vers la page cible.php qui reçoit les données du formulaire, comme vous le montre la figure suivante.

Fonctionnement d'un formulaire
Fonctionnement d'un formulaire

Le nom de la page cible est défini grâce à l'attribut action.

Retenez donc bien que vous travaillez normalement sur deux pages différentes : la page qui contient le formulaire (formulaire.php dans notre exemple), et celle qui reçoit les données du formulaire pour les traiter (cible.php).

Les éléments du formulaire

Dans un formulaire, vous le savez peut-être déjà, on peut insérer beaucoup d'éléments différents : zones de texte, boutons, cases à cocher, etc.
Je vais ici tous les énumérer et vous montrer comment vous servir de chacun d'eux dans la page cible.php qui fera le traitement. Vous allez voir, c'est vraiment très simple : au lieu de recevoir un array $_GET, vous allez recevoir un array $_POST contenant les données du formulaire !

Les petites zones de texte

Une zone de texte ressemble à la figure suivante.

Zone de texte
Zone de texte

En HTML, on l'insère tout simplement avec la balise :

<input type="text" />

Il y a deux attributs à connaître que l'on peut ajouter à cette balise.

  • name (obligatoire) : c'est le nom de la zone de texte. Choisissez-le bien, car c'est lui qui va produire une variable. Par exemple :
    <input type="text" name="pseudo" />.

  • value (facultatif) : c'est ce que contient la zone de texte au départ. Par défaut, la zone de texte est vide mais il peut être pratique de pré-remplir le champ. Exemple :
    <input type="text" name="pseudo" value="M@teo21" />.

Oui, je sais que vous commencez à vous inquiéter car vous n'avez pas encore vu de PHP pour le moment mais n'ayez pas peur. Le fonctionnement est tout simple et a un air de déjà vu. Le texte que le visiteur aura entré sera disponible dans cible.php sous la forme d'une variable appelée $_POST['pseudo'].

Pour l'exemple, je vous propose de créer un formulaire qui demande le prénom du visiteur puis qui l'affiche fièrement sur la page cible.php. On va donc distinguer deux codes source : celui de la page du formulaire et celui de la page cible.

Voici le code de la page formulaire.php :

<p>
    Cette page ne contient que du HTML.<br />
    Veuillez taper votre prénom :
</p>

<form action="cible.php" method="post">
<p>
    <input type="text" name="prenom" />
    <input type="submit" value="Valider" />
</p>
</form>

Maintenant, je vous propose de créer la page cible.php. Cette page va recevoir le prénom dans une variable nommée $_POST['prenom'].

<p>Bonjour !</p>

<p>Je sais comment tu t'appelles, hé hé. Tu t'appelles <?php echo $_POST['prenom']; ?> !</p>

<p>Si tu veux changer de prénom, <a href="formulaire.php">clique ici</a> pour revenir à la page formulaire.php.</p>

Le code web suivant ouvre la page formulaire.php pour que vous puissiez tester.

Essayer !

Dans cible.php on a affiché une variable $_POST['prenom'] qui contient ce que l'utilisateur a entré dans le formulaire.

Les grandes zones de texte

La grande zone de texte (on l'appelle aussi « zone de saisie multiligne ») ressemble à la figure suivante.

Une grande zone de texte
Une grande zone de texte

On peut y écrire autant de lignes que l'on veut. C'est plus adapté si le visiteur doit écrire un long message, par exemple.

On va utiliser le code HTML suivant pour insérer cette zone de texte :

<textarea name="message" rows="8" cols="45">
Votre message ici.
</textarea>

Là encore, on a un attribut name qui va définir le nom de la variable qui sera créée dans cible.php. Dans notre cas, ce sera la variable $_POST['message'].

Vous remarquerez qu'il n'y a pas d'attribut value. En fait, le texte par défaut est ici écrit entre le <textarea> et le </textarea>. Si vous ne voulez rien mettre par défaut, alors n'écrivez rien entre <textarea> et </textarea>.

La liste déroulante

La figure suivante est une liste déroulante.

Une liste déroulante
Une liste déroulante

On utilise le code HTML suivant pour construire une liste déroulante :

<select name="choix">
    <option value="choix1">Choix 1</option>
    <option value="choix2">Choix 2</option>
    <option value="choix3">Choix 3</option>
    <option value="choix4">Choix 4</option>
</select>

Tout bêtement, on utilise la balise <select> à laquelle on donne un nom (ici : « choix »). On écrit ensuite les différentes options disponibles… puis on referme la balise avec </select>.

Ici, une variable $_POST['choix'] sera créée, et elle contiendra le choix qu'a fait l'utilisateur. S'il a choisi « Choix 3 », la variable $_POST['choix'] sera égale au value correspondant, c'est-à-dire choix3.

Vous pouvez aussi définir le choix par défaut de la liste. Normalement c'est le premier, mais si vous rajoutez l'attribut selected="selected" à une balise <option>, alors ce sera le choix par défaut. On pourrait par exemple écrire :

<option value="choix3" selected="selected">Choix 3</option>

Les cases à cocher

La figure suivante représente une série de cases à cocher.

Cases à cocher
Cases à cocher

On utilisera le code suivant pour afficher des cases à cocher :

<input type="checkbox" name="case" id="case" /> <label for="case">Ma case à cocher</label>

Là encore, on donne un nom à la case à cocher via l'attribut name (ici : « case »). Ce nom va générer une variable dans la page cible, par exemple $_POST['case'].

  • Si la case a été cochée, alors $_POST['case'] aura pour valeur « on ».

  • Si elle n'a pas été cochée, alors $_POST['case'] n'existera pas. Vous pouvez faire un test avec isset($_POST['case']) pour vérifier si la case a été cochée ou non.

Si vous voulez que la case soit cochée par défaut, il faudra lui rajouter l'attribut checked="checked". Par exemple :

<input type="checkbox" name="case" checked="checked" />

Les boutons d'option

Les boutons d'option fonctionnent par groupes de deux minimum. Vous trouverez un exemple sur la figure suivante.

Boutons d'option
Boutons d'option

Le code correspondant à cet exemple est le suivant :

Aimez-vous les frites ?
<input type="radio" name="frites" value="oui" id="oui" checked="checked" /> <label for="oui">Oui</label>
<input type="radio" name="frites" value="non" id="non" /> <label for="non">Non</label>

Comme vous pouvez le voir, les deux boutons d'option ont le même nom (« frites »). C'est très important, car ils fonctionnent par groupes : tous les boutons d'option d'un même groupe doivent avoir le même nom. Cela permet au navigateur de savoir lesquels désactiver quand on active un autre bouton du groupe. Il serait bête en effet de pouvoir sélectionner à la fois « Oui » et « Non ».

Pour pré-cocher l'un de ces boutons, faites comme pour les cases à cocher : rajoutez un attribut checked="checked". Ici, comme vous pouvez le voir, « Oui » est sélectionné par défaut.

Dans la page cible, une variable $_POST['frites'] sera créée. Elle aura la valeur du bouton d'option choisi par le visiteur, issue de l'attribut value. Si on aime les frites, alors on aura $_POST['frites'] = 'oui'.

Il faut bien penser à renseigner l'attribut value du bouton d'option car c'est lui qui va déterminer la valeur de la variable.

Les champs cachés

Les champs cachés constituent un type de champ à part. En quoi ça consiste ? C'est un code dans votre formulaire qui n'apparaîtra pas aux yeux du visiteur, mais qui va quand même créer une variable avec une valeur. On peut s'en servir pour transmettre des informations fixes.

Je m'explique : supposons que vous ayez besoin de « retenir » que le pseudo du visiteur est « Mateo21 ». Vous allez taper ce code :

<input type="hidden" name="pseudo" value="Mateo21" />

À l'écran, sur la page web on ne verra rien. Mais dans la page cible, une variable $_POST['pseudo'] sera créée, et elle aura la valeur « Mateo21 » !

C'est apparemment inutile, mais vous verrez que vous en aurez parfois besoin.

Ne faites jamais confiance aux données reçues : la faille XSS

Vous vous souvenez des mises en garde que j'avais faites dans le chapitre précédent ? Elles ne concernaient pas que les paramètres qui transitent par l'URL : tout cela vaut aussi pour les formulaires !

Mais… autant je vois comment on peut modifier l'URL, autant je ne comprends pas comment peut faire un visiteur pour modifier le formulaire de mon site et trafiquer les données !

On a tendance à croire que les visiteurs ne peuvent pas « bidouiller » le formulaire mais c'est faux. Je vais dans un premier temps vous montrer pourquoi les formulaires ne sont pas plus sûrs que les URL, puis je vous parlerai d'un autre danger important : la faille XSS. Avec ça, nous aurons vraiment fait le tour de ce qu'il faut savoir pour être tranquilles par la suite !

Pourquoi les formulaires ne sont pas sûrs

Tout ce que nous avons appris dans le chapitre précédent sur les URL reste valable ici. Toutes les informations qui proviennent de l'utilisateur, à savoir les données de $_GET et de $_POST, doivent être traitées avec la plus grande méfiance.

Vous ne pouvez pas supposer que vous allez recevoir ce que vous attendiez.

Cette règle est très simple, mais je vous propose un exemple concret pour bien visualiser le problème. Imaginez que vous demandez à vos visiteurs de rentrer dans un champ leur date de naissance au format JJ/MM/AAAA. Combien vont respecter cette mise en forme ? Combien vont se tromper par erreur ? Je vous garantis que parmi tous vos visiteurs, alors que vous attendiez quelque chose comme « 04/10/1987 », vous allez tomber sur une personne qui va écrire : « Je suis né le 4 octobre 1987 ». C'est un exemple un peu extrême mais ça va vous arriver, soyez-en sûrs. Par conséquent, quand vous ferez le traitement de la date en PHP, il faudra bien vérifier qu'elle respecte le format que vous avez indiqué.

De la même manière, comme dans le chapitre précédent, même si vous demandez un nombre compris entre 1 et 100, il y aura bien quelqu'un pour écrire « 48451254523 ». Soyez donc vigilants et n'ayez jamais confiance en ce qui vient de l'utilisateur, à savoir les données issues des arrays $_GET et $_POST.

Avec les formulaires, vous ne pouvez pas non plus supposer qu'on va vous envoyer tous les champs que vous attendiez. Un visiteur peut très bien s'amuser à supprimer un champ de texte, et dans ce cas votre page cible.php ne recevra jamais le texte qu'elle attendait ! Il faudra impérativement qu'elle vérifie que toutes les données qu'elle attendait sont bien là avant d'effectuer la moindre opération.

Puisque la page du formulaire se trouve sur mon site, comment peut faire un visiteur pour modifier ma page web ? Il peut voir les sources mais pas les modifier !

En effet, vos visiteurs ne peuvent pas modifier vos pages web sur le serveur… Mais ils peuvent les reprendre et les modifier ailleurs.

Souvenez-vous du schéma de la figure suivante :

Image utilisateur

La page formulaire.php contient le formulaire et cible.php traite les données qu'on lui a envoyées. Autant le code PHP n'est jamais visible par vos visiteurs, autant le code HTML du formulaire, lui, peut être vu par tout le monde.

À partir de là, qu'est-ce qui empêche quelqu'un de créer une copie légèrement modifiée de votre formulaire et de la stocker sur son serveur, à l'image de la figure suivante ?

Le formulaire modifié
Le formulaire modifié

Sur le schéma de la figure suivante, le « méchant » (nous l'appellerons comme ça, parce que ça lui va bien. ;-)) a pris le code HTML de votre formulaire, l'a modifié et l'a enregistré sur son serveur (ou même sur son ordinateur). L'attribut action a été modifié pour indiquer l'adresse absolue (donc complète) de votre page cible :

<form method="post" action="http://www.monsite.com/cible.php">

Le méchant peut maintenant modifier votre formulaire, ajouter des champs, en supprimer, bref faire ce qu'il veut avec ! Votre page cible.php n'y verra que du feu car il est impossible de savoir avec certitude de quel formulaire vient le visiteur.

Ces explications sont assez techniques. En fait, on les réserve normalement aux personnes plus expérimentées que les débutants. Cependant, je tenais volontairement à vous montrer comment c'est possible. Même si tout n'est pas totalement clair dans votre tête, vous avez au moins l'idée du mode de fonctionnement.

S'il y a une chose à retenir ici, c'est que les formulaires sont modifiables par tous les visiteurs contrairement à ce qu'on pourrait penser. Par conséquent, votre page cible.php devra être aussi vigilante que nous l'avons été dans le chapitre précédent et ne pas faire confiance aux données de l'utilisateur (les programmeurs ont d'ailleurs une maxime : « Never trust user input », ce qui signifie « Ne faites jamais confiance aux données de l'utilisateur »).

La faille XSS : attention au code HTML que vous recevez !

Il nous reste un dernier point important à voir ensemble et après, j'arrête de vous faire peur, promis !

La faille XSS (pour cross-site scripting) est vieille comme le monde (euh, comme le Web) et on la trouve encore sur de nombreux sites web, même professionnels ! C'est une technique qui consiste à injecter du code HTML contenant du JavaScript dans vos pages pour le faire exécuter à vos visiteurs.

Reprenons la page qui affiche le prénom qu'on lui envoie. Elle contient notamment le code suivant :

<p>Je sais comment tu t'appelles, hé hé. Tu t'appelles <?php echo $_POST['prenom']; ?> !</p>

Si le visiteur décide d'écrire du code HTML à la place de son prénom, cela fonctionnera très bien ! Par exemple, imaginons qu'il écrive dans le champ « Prénom » le code : <strong>Badaboum</strong>. Le code source HTML qui sera généré par PHP sera le suivant :

<p>Je sais comment tu t'appelles, hé hé. Tu t'appelles <strong>Badaboum</strong> !</p>

Et alors ? S'il veut mettre son prénom en gras, c'est son problème, non ?

Outre le fait qu'il peut insérer n'importe quel code HTML (et rendre votre page invalide), ce qui n'est pas le plus grave, il peut aussi ouvrir des balises de type <script> pour faire exécuter du code JavaScript au visiteur qui visualisera la page !

<p>Je sais comment tu t'appelles, hé hé. Tu t'appelles <script type="text/javascript">alert('Badaboum')</script> !</p>

Tous les visiteurs qui arriveront sur cette page verront une boîte de dialogue JavaScript s'afficher. Plutôt gênant. Voyez la figure suivante.

Exécution de JavaScript par la faille XSS
Exécution de JavaScript par la faille XSS

Résoudre le problème est facile : il faut protéger le code HTML en l'échappant, c'est-à-dire en affichant les balises (ou en les retirant) plutôt que de les faire exécuter par le navigateur, comme sur la figure suivante.

Éviter la faille XSS en échappant le HTML
Éviter la faille XSS en échappant le HTML

Pour échapper le code HTML, il suffit d'utiliser la fonction htmlspecialchars qui va transformer les chevrons des balises HTML <> en &lt; et &gt; respectivement. Cela provoquera l'affichage de la balise plutôt que son exécution.

<p>Je sais comment tu t'appelles, hé hé. Tu t'appelles <?php echo htmlspecialchars($_POST['prenom']); ?> !</p>

Le code HTML qui en résultera sera propre et protégé car les balises HTML insérées par le visiteur auront été échappées :

<p>Je sais comment tu t'appelles, hé hé. Tu t'appelles &lt;strong&gt;Badaboum&lt;/strong&gt; !</p>

L'envoi de fichiers

Vous saviez qu'on pouvait aussi envoyer des fichiers grâce aux formulaires ? Vous aurez besoin de lire cette section si vous voulez que vos visiteurs puissent envoyer (on dit aussi uploader) des images, des programmes ou tout autre type de fichier sur votre site.

Là encore, ça se passe en deux temps.

  1. Le visiteur arrive sur votre formulaire et le remplit (en indiquant le fichier à envoyer). Une simple page HTML suffit pour créer le formulaire.

  2. PHP réceptionne les données du formulaire et, s'il y a des fichiers dedans, il les « enregistre » dans un des dossiers du serveur.

On va commencer par créer le formulaire permettant d'envoyer un fichier (une simple page HTML).
Nous verrons ensuite comment traiter l'envoi du fichier côté serveur avec PHP.

Le formulaire d'envoi de fichier

Dès l'instant où votre formulaire propose aux visiteurs d'envoyer un fichier, il faut ajouter l'attribut enctype="multipart/form-data" à la balise <form>.

<form action="cible_envoi.php" method="post" enctype="multipart/form-data">
    <p>Formulaire d'envoi de fichier</p>
</form>

Grâce à enctype, le navigateur du visiteur sait qu'il s'apprête à envoyer des fichiers.

Maintenant que c'est fait, nous pouvons ajouter à l'intérieur du formulaire une balise permettant d'envoyer un fichier. C'est une balise très simple de type <input type="file" />. Il faut penser comme toujours à donner un nom à ce champ de formulaire (grâce à l'attribut name) pour que PHP puisse reconnaître le champ par la suite.

<form action="cible_envoi.php" method="post" enctype="multipart/form-data">
        <p>
                Formulaire d'envoi de fichier :<br />
                <input type="file" name="monfichier" /><br />
                <input type="submit" value="Envoyer le fichier" />
        </p>
</form>

Voilà, c'est suffisant.

Vous pouvez ajouter d'autres champs plus classiques au formulaire (champ de texte, cases à cocher). Vous pouvez aussi proposer d'envoyer plusieurs fichiers en même temps.
Là, on va se contenter d'un seul champ (envoi de fichier) pour faire simple.

Le traitement de l'envoi en PHP

Comme vous avez dû le remarquer, le formulaire pointe vers une page PHP qui s'appelle cible_envoi.php. Le visiteur sera donc redirigé sur cette page après l'envoi du formulaire.

C'est maintenant que ça devient important. Il faut que l'on écrive le code de la page cible_envoi.php pour traiter l'envoi du fichier.

« Traiter l'envoi du fichier » ? C'est-à-dire ?
Si le fichier a été envoyé sur le serveur c'est bon, non ? Qu'est-ce que PHP aurait besoin de faire ?

En fait, au moment où la page PHP s'exécute, le fichier a été envoyé sur le serveur mais il est stocké dans un dossier temporaire.
C'est à vous de décider si vous acceptez définitivement le fichier ou non. Vous pouvez par exemple vérifier si le fichier a la bonne extension (si vous demandiez une image et qu'on vous envoie un « .txt », vous devrez refuser le fichier).

Si le fichier est bon, vous l'accepterez grâce à la fonction move_uploaded_file, et ce, d'une manière définitive.

Mais comment je sais si « le fichier est bon » ?

Pour chaque fichier envoyé, une variable $_FILES['nom_du_champ'] est créée. Dans notre cas, la variable s'appellera $_FILES['monfichier'].
Cette variable est un tableau qui contient plusieurs informations sur le fichier :

Variable

Signification

$_FILES['monfichier']['name']

Contient le nom du fichier envoyé par le visiteur.

$_FILES['monfichier']['type']

Indique le type du fichier envoyé. Si c'est une image gif par exemple, le type sera image/gif.

$_FILES['monfichier']['size']

Indique la taille du fichier envoyé. Attention : cette taille est en octets. Il faut environ 1 000 octets pour faire 1 Ko, et 1 000 000 d'octets pour faire 1 Mo.
Attention : la taille de l'envoi est limitée par PHP. Par défaut, impossible d'uploader des fichiers de plus de 8 Mo.

$_FILES['monfichier']['tmp_name']

Juste après l'envoi, le fichier est placé dans un répertoire temporaire sur le
serveur en attendant que votre script
PHP décide si oui ou non il accepte de
le stocker pour de bon. Cette variable
contient l'emplacement temporaire du
fichier (c'est PHP qui gère ça).

$_FILES['monfichier']['error']

Contient un code d'erreur permettant de savoir si l'envoi s'est bien effectué ou s'il
y a eu un problème et si oui, lequel. La
variable vaut 0 s'il n'y a pas eu d'erreur.

Je vous propose de faire les vérifications suivantes pour décider si l'on accepte le fichier ou non.

  1. Vérifier tout d'abord si le visiteur a bien envoyé un fichier (en testant la variable $_FILES['monfichier'] avec isset()) et s'il n'y a pas eu d'erreur d'envoi (grâce à $_FILES['monfichier']['error']).

  2. Vérifier si la taille du fichier ne dépasse pas 1 Mo par exemple (environ 1 000 000 d'octets) grâce à $_FILES['monfichier']['size'].

  3. Vérifier si l'extension du fichier est autorisée (il faut interdire à tout prix que les gens puissent envoyer des fichiers PHP, sinon ils pourraient exécuter des scripts sur votre serveur). Dans notre cas, nous autoriserons seulement les images (fichiers .png, .jpg, .jpeg et .gif).
    Nous analyserons pour cela la variable $_FILES['monfichier']['name'].

Nous allons donc faire une série de tests dans notre page cible_envoi.php.

1/ Tester si le fichier a bien été envoyé

On commence par vérifier qu'un fichier a été envoyé. Pour cela, on va tester si la variable $_FILES['monfichier'] existe avec isset().
On vérifie dans le même temps s'il n'y a pas d'erreur d'envoi.

<?php
// Testons si le fichier a bien été envoyé et s'il n'y a pas d'erreur
if (isset($_FILES['monfichier']) AND $_FILES['monfichier']['error'] == 0)
{
 
}
?>
2/ Vérifier la taille du fichier

On veut interdire que le fichier dépasse 1 Mo, soient environ 1 000 000 d'octets (j'arrondis pour simplifier). On doit donc tester $_FILES['monfichier']['size'] :

<?php
// Testons si le fichier a bien été envoyé et s'il n'y a pas d'erreur
if (isset($_FILES['monfichier']) AND $_FILES['monfichier']['error'] == 0)
{
        // Testons si le fichier n'est pas trop gros
        if ($_FILES['monfichier']['size'] <= 1000000)
        {
 
        }
}
?>
3/ Vérifier l'extension du fichier

On peut récupérer l'extension du fichier dans une variable grâce à ce code :

<?php
$infosfichier = pathinfo($_FILES['monfichier']['name']);
$extension_upload = $infosfichier['extension'];
?>

La fonction pathinfo renvoie un array contenant entre autres l'extension du fichier dans $infosfichier['extension']. On stocke ça dans une variable $extension_upload.

Une fois l'extension récupérée, on peut la comparer à un tableau d'extensions autorisées (un array) et vérifier si l'extension récupérée fait bien partie des extensions autorisées à l'aide de la fonction in_array().

Ouf ! On obtient ce code au final :

<?php
// Testons si le fichier a bien été envoyé et s'il n'y a pas d'erreur
if (isset($_FILES['monfichier']) AND $_FILES['monfichier']['error'] == 0)
{
        // Testons si le fichier n'est pas trop gros
        if ($_FILES['monfichier']['size'] <= 1000000)
        {
                // Testons si l'extension est autorisée
                $infosfichier = pathinfo($_FILES['monfichier']['name']);
                $extension_upload = $infosfichier['extension'];
                $extensions_autorisees = array('jpg', 'jpeg', 'gif', 'png');
                if (in_array($extension_upload, $extensions_autorisees))
                {
                
                }
        }
}
?>
4/ Valider l'upload du fichier

Si tout est bon, on accepte le fichier en appelant move_uploaded_file().
Cette fonction prend deux paramètres :

  • le nom temporaire du fichier (on l'a avec $_FILES['monfichier']['tmp_name']) ;

  • le chemin qui est le nom sous lequel sera stocké le fichier de façon définitive. On peut utiliser le nom d'origine du fichier $_FILES['monfichier']['name'] ou générer un nom au hasard.

Je propose de placer le fichier dans un sous-dossier « uploads ».
On gardera le même nom de fichier que celui d'origine. Comme $_FILES['monfichier']['name'] contient le chemin entier vers le fichier d'origine (C:\dossier\fichier.png par exemple), il nous faudra extraire le nom du fichier. On peut utiliser pour cela la fonction basename qui renverra juste « fichier.png ».

<?php
// Testons si le fichier a bien été envoyé et s'il n'y a pas d'erreur
if (isset($_FILES['monfichier']) AND $_FILES['monfichier']['error'] == 0)
{
        // Testons si le fichier n'est pas trop gros
        if ($_FILES['monfichier']['size'] <= 1000000)
        {
                // Testons si l'extension est autorisée
                $infosfichier = pathinfo($_FILES['monfichier']['name']);
                $extension_upload = $infosfichier['extension'];
                $extensions_autorisees = array('jpg', 'jpeg', 'gif', 'png');
                if (in_array($extension_upload, $extensions_autorisees))
                {
                        // On peut valider le fichier et le stocker définitivement
                        move_uploaded_file($_FILES['monfichier']['tmp_name'], 'uploads/' . basename($_FILES['monfichier']['name']));
                        echo "L'envoi a bien été effectué !";
                }
        }
}
?>

Ce script est un début, mais en pratique il vous faudra sûrement encore l'améliorer. Par exemple, si le nom du fichier contient des espaces ou des accents, ça posera un problème une fois envoyé sur le Web. D'autre part, si quelqu'un envoie un fichier qui a le même nom que celui d'une autre personne, l'ancien sera écrasé !

La solution consiste en général à « choisir » nous-mêmes le nom du fichier stocké sur le serveur plutôt que de se servir du nom d'origine. Vous pouvez faire un compteur qui s'incrémente : 1.png, 2.png, 3.jpg, etc.

Pour aller plus loin, je vous recommande de lire le tutoriel de DHKold sur l'upload de fichiers par formulaire qui traite le sujet plus en détail.

Bonne lecture !

En résumé

  • Les formulaires sont le moyen le plus pratique pour le visiteur de transmettre des informations à votre site. PHP est capable de récupérer les données saisies par vos visiteurs et de les traiter.

  • Les données envoyées via un formulaire se retrouvent dans un array $_POST.

  • De la même manière que pour les URL, il ne faut pas donner sa confiance absolue aux données que vous envoie l'utilisateur. Il pourrait très bien ne pas remplir tous les champs voire trafiquer le code HTML de la page pour supprimer ou ajouter des champs. Traitez les données avec vigilance.

  • Que ce soit pour des données issues de l'URL ($_GET) ou d'un formulaire ($_POST), il faut s'assurer qu'aucun texte qui vous est envoyé ne contient du HTML si celui-ci est destiné à être affiché sur une page. Sinon, vous ouvrez une faille appelée XSS qui peut être néfaste pour la sécurité de votre site.

  • Pour éviter la faille XSS, il suffit d'appliquer la fonction htmlspecialchars sur tous les textes envoyés par vos visiteurs que vous afficherez.

  • Les formulaires permettent d'envoyer des fichiers. On retrouve les informations sur les fichiers envoyés dans un array $_FILES. Leur traitement est cependant plus complexe.

Exemple de certificat de réussite
Exemple de certificat de réussite