Sommaire
Formulaire d'upload (vue)
Pour pouvoir téléverser (upload) un fichier, nous allons devoir faire appel à un nouveau type
d'input.
De plus nous allons être obligé de passer en méthode POST, impossible d'envoyer un fichier à travers
l'url avec GET évidement.
Il nous faudra en plus de cela rajouter une information à notre balise form.
<form action="" method="post" enctype="multipart/form-data">
<label for="fichier">Choisi un fichier</label>
<input type="file" name="fichier" id="fichier">
<input type="submit" value="Envoyer">
<span><?php echo $fileEr; ?></span>
</form>
Comme vous pouvez le voir, notre formulaire contient l'attribut "enctype" auquel on a donné la valeur "multipart/form-data". Celui ci sert à préciser que dans les données envoyé, nous avons un fichier via un input type "file".
Traitement des données (contrôleur)
Maintenant que nous avons envoyé nos données avec notre formulaire, il nous faut les traiter.
Traiter les données d'un fichier nous demande plus de travail que pour vérifier une simple
chaîne de caractère.
<?php
$fileEr = "";
// target_dir contient le chemin vers le dossier d'upload.
$target_dir = "../upload/";
// On liste dans un tableau les types mimes des fichiers que l'on accepte.
$typesPermis = ['image/png', 'image/jpeg', 'application/pdf'];
// Arrive t-on en méthode POST ?
if($_SERVER["REQUEST_METHOD"] == "POST"){
// Y a t-il un fichier uploadé dans nos fichiers temporaires.
if(!is_uploaded_file($_FILES['fichier']['tmp_name'])){
$fileEr = "Veuillez sélectionner un fichier";
}else{
# --- Ici toute les vérifications faite sur le fichier --- #
}
if(empty($fileEr)){
# --- Ici la fin de l'upload si il n'y a pas d'erreur --- #
}
}
include("../views/upload.php");
?>
On défini juste au dessus le chemin vers où sont enregistré nos fichiers uploadé.
Nous pourrions d'ailleurs déclarer ceci dans notre fichier de configuration.
Ensuite nous voyons la classique vérification que nous arrivons ici en méthode POST.
Puis on voit une nouvelle super global. $_FILES contient 5 infos principales :
- Le nom du fichier "name"
- Le poid du fichier en octet "size"
- Le type mime du fichier "type"
- Le message d'erreur si il y en a un "error"
- Le nom et emplacement temporaire du fichier "tmp_name"
Mais on va voir par la suite que l'on ne se servira pas du "type" car trop facile à berner.
L'erreur peut être utile en vérifiant par exemple qu'il n'y en a pas, mais je m'en passerais ici.
Nous allons donc faire usage des trois autres.
// On donne un nouveau nom au fichier
$target_file = $target_dir . uniqid('', true) ."-". basename($_FILES["fichier"]["name"]);
// On récupère le type mime du fichier dans le dossier temporaire.
$mime_type = mime_content_type($_FILES['fichier']['tmp_name']);
Dans une nouvelle variable, on concatène 4 chaînes de caractère.
- Le chemin vers le dossier d'upload.
- Un uniqid, une chaîne de caractère aléatoire pour éviter d'avoir deux fichiers portant le même nom.
- Un tiret pour séparer l'uniqid du véritable nom.
- Et le véritable nom si on souhaite garder celui ci.
basename sert à retirer tout possible chemin de fichier qui se serait incrusté pour ne garder
que le nom du fichier.
Ensuite mime_content_type() sert à récupérer dans le fichier enregistré en zone temporaire,
le véritable type du fichier, au contraire de $_FILES qui récupère ce que HTML lui envoi,
cette fonction va véritablement lire le type du fichier.
// On vérifie si le fichier existe déjà.
if(file_exists($target_file)){
$fileEr = "Ce fichier existe déjà.";
}
// On vérifie si le fichier n'est pas trop lourd
// Poid en octet
if($_FILES["fichier"]["size"] > 500000){
$fileEr = "Ce fichier est trop gros";
}
// On vérifie que le fichier est du type voulu.
if(!in_array($mime_type, $typesPermis)){
$fileEr = "Ce type de fichier n'est pas accepté";
}
Ensuite on vérifie que malgré le nom aléatoire, on n'a pas déjà un fichier du même nom,
peu probable mais ça ne coûte rien de vérifier.
Que le poid du fichier n'est pas trop lourd. Sur ce sujet, pensez à vérifier votre fichier
php.ini qui contient tout les paramètres de PHP, ici aussi la taille de vos fichiers
peut être limité.
Et ensuite si le type du fichier est bien dans notre tableau de type accepté.
# --- dans le if(empty($fileEr)) --- #
if(move_uploaded_file($_FILES["fichier"]["tmp_name"],$target_file)){
echo "Votre fichier à bien été téléversé";
/* --- Si le fichier doit être facilement retrouvé ou lié à un utilisateur,
On pourrait enregistrer le nom du fichier en base de donnée --- */
}else{
$fileEr = "Erreur lors de l'upload";
}
Si on a pas eu d'erreur, alors on utilise la fonction "move_uploaded_file()" pour déplacer
notre fichier depuis le dossier temporaire où tout sera supprimé jusqu'à notre dossier d'upload.
Le premier argument prend le chemin vers le dossier temporaire et le nom du fichier, alors que le
second argument prend le chemin vers le dossier choisi avec le nom de fichier choisi.
Si il y a une erreur lors du mouvement, la fonction renverra false et si tout se passe bien true,
On peut donc s'en servir dans un if et faire des actions différentes en cas de succès ou d'échec.