Ce développement permet d’uploader facilement des fichiers en utilisant une class PHP maison.
Une option non obligatoire permet de coupler ce système d’upload avec un système de drag & drop Jquery.
Pré-requis
- Avoir dans le dossier /src/Outil/ la class Url.php permettant la création de slug
- Avoir à disposition la version 3.6.0 ou + de la bibliothèque Jquery
Class PHP
Dans le dossier /src/Outil/ créer un fichier Upload.php et y placer le code ci-dessous.
<?php
/**
* Created by PhpStorm.
* User: Graffagnino David
* Société : DGWWW - https://dgwww.fr
* Date: 21/06/2022
* Time: 08:38
*/
namespace App\Outil;
/**
* https://www.w3schools.com/php/php_file_upload.asp
* https://developer.mozilla.org/fr/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
*/
class Upload
{
/**
* @var bool
*/
private $_etat = true;
/**
* @var string
*/
private $_message_erreur = "";
/**
* @var string
*/
private $_extention = "";
/**
* @var string
*/
private $_fichier_uploader = "";
/**
* Upload d'un fichier
* @param $fichier
* @param $params
*/
public function __construct($fichier, $params){
/*
* Verrification
*/
$this->_verrification($fichier, $params);
/*
* Upload
*/
if($this->_etat == true) {
$this->_fichier_uploader = trim($params["nom_fichier"]) . "." . $this->_extention;
move_uploaded_file($fichier["tmp_name"], trim($params["chemin_upload"]) . "/" . $this->_fichier_uploader);
}
}
/**
* Retourne l'état de l'upload
* @return bool
*/
public function etat(){
return $this->_etat;
}
/**
* Retourne le message d'erreur de l'upload
* @return string
*/
public function message_erreur(){
return $this->_message_erreur;
}
/**
* Retourne le nom du fichier uploadé
* @return string
*/
public function fichier_uploader(){
return $this->_fichier_uploader;
}
/**
* Verrification des parramètres nécessaire à l'upload
* @param $fichier
* @param $params
* @return void
*/
private function _verrification($fichier, $params){
// Fichier
if($fichier == null){
$this->_etat = false;
$this->_message_erreur = "La variable <b>fichier</b> est manquante";
}else {
// Nom
if (isset($params["nom_fichier"]) == false || trim($params["nom_fichier"]) == "") {
$this->_etat = false;
$this->_message_erreur = "Le paramètre <b>nom_fichier</b> est manquant";
}
// Chemin
if (isset($params["chemin_upload"]) == false || trim($params["chemin_upload"]) == "") {
$this->_etat = false;
$this->_message_erreur .= "<br />Le paramètre <b>chemin_upload</b> est manquant";
}
// Type upload authorisé
if (isset($params["type_upload"]) == false) {
$this->_etat = false;
$this->_message_erreur .= "<br />Le paramètre <b>type_upload</b> est manquant";
} else {
$extention_valide = false;
$nom_fichier_temporaire = basename($fichier["name"]);
$this->_extention = strtolower(pathinfo($nom_fichier_temporaire,PATHINFO_EXTENSION));
foreach ($params["type_upload"] as $ty){
if($this->_extention == str_replace(".", "", $ty)){
$extention_valide = true;
break;
}
}
if($extention_valide == false){
$this->_etat = false;
$this->_message_erreur .= "<br />L'extention du fichier n'est pas valide";
}
}
// Taille upload maximum authorisé (exprimé en mo)
// 100000 = 100kb
if (isset($params["taille_upload"]) == false) {
$this->_etat = false;
$this->_message_erreur .= "<br />Le paramètre <b>taille_upload</b> est manquant";
} else {
$taille = $params["taille_upload"] * 1000 * 1000;
if($fichier["size"] > $taille){
$this->_etat = false;
$this->_message_erreur .= "<br />La taille du fichier est supérieur à la limite autorisé";
}
}
}
}
}
La fonction etat() renvoise true ou false si l’ensemble des vérifications sont validées ou non
La fonction message_erreur() renvois les messages d’erreur rencontrés lors de la tentative de validation
La fonction fichier_uploader() renvois le nom fichier ainsi que son extention
Configuration et déclenchement de l’upload dans le controller
$dossier = $this->getParameter("visuels_produits");
$params = [
"nom_fichier" => "test-upload-" . date("Ymd-hms"),
"chemin_upload" => $dossier,
"type_upload" => [
"jpg",
"png",
"jpeg",
"gif"
],
"taille_upload" => 0.5
];
$upload = new Upload($_FILES["fichier"], $params);
if($upload->etat() == true)
echo "Le fichier " . $upload->fichier_uploader() . " a correctement été uploadé";
else
echo "Erreur durant l'upload";
nom_fichier : Nom que prendra le fichier à la fin de l’upload
chemin_upload : Chemin où sera uploadé le fichier
type_upload : Tableau des formats de fichier autorisés pour l’upload. Attention à ne pas mettre de point avant l’extention
taille_upload : Taille maximale autorisé pour l’upload. La taille est exprimée en MO
Attention : $_FILES[« fichier »] ici est lié au name du champ input type file du formulaire. Si jamais le système Drag & drop est implémenté, il fait référence à la valeur de la variable javaScript _upload_nom_variable_fichier du fichier upload.js
HTML
Code HTML du formulaire simple
<form action="[ACTION DU FORMULAIRE]" method="post" enctype="multipart/form-data">
<input type="file" name="fichier" id="fichier" />
</form>
Drag & drop + Upload
Créer un fichier upload.js dans le dossier js du projet et y placer le code suivant
$(document).ready(function(){
let _upload_class_zone_upload = '.dgwww_zone_upload'
let _upload_class_input_file = '.dgwww_input_file_upload'
let _upload_nom_variable_fichier = 'fichier' // Utiliser dans le traitement PHP
let _upload_class_zone_preview = '.dgwww_zone_preview'
/*
* Blocage de la redirection de la page
*/
$("html").on("dragover", function(e) {
e.preventDefault();
e.stopPropagation();
});
$("html").on("drop", function(e) { e.preventDefault(); e.stopPropagation(); });
/*
* Entrer et sortir de la zone de drag and drop
*/
$(_upload_class_zone_upload).on('dragenter', function (e) {
e.stopPropagation();
e.preventDefault();
$(_upload_class_zone_upload + " .message").text("Déposer le fichier");
});
$(_upload_class_zone_upload).on('dragover', function (e) {
e.stopPropagation();
e.preventDefault();
$(_upload_class_zone_upload + " .message").text("Déposer le fichier");
});
/*
* Clique dans la zone de drag and drop
*/
$(_upload_class_zone_upload).click(function(){
$(_upload_class_input_file).click();
});
/*
* Déposer le fichier en upload
*/
$(_upload_class_zone_upload).on('drop', function (e) {
e.stopPropagation();
e.preventDefault();
$(_upload_class_zone_upload + " .message").text("Upload du fichier en cours ...");
var file = e.originalEvent.dataTransfer.files;
var fd = new FormData();
fd.append(_upload_nom_variable_fichier, file[0]);
_upload(fd);
});
/*
* Changement de valeur du champs upload
*/
$(_upload_class_input_file).change(function() {
var fd = new FormData();
var files = $(_upload_class_input_file)[0].files[0];
fd.append(_upload_nom_variable_fichier, files);
_upload(fd);
})
/*
* Fonction d'upload
*/
function _upload(input_file_data){
let url = "produits/upload"
// Ajout de valeur spécifique
$.ajax({
url: url,
type: 'post',
data: input_file_data,
contentType: false,
processData: false,
success: function(response){
if(response != 0){
$(_upload_class_zone_preview + " span").after("<img src='" + response + "' alt='' />")
$(_upload_class_zone_upload + " .message").text("Upload terminé");
}else{
alert("Erreur dans l'upload du fichier");
}
},
});
}
})
_upload_nom_variable_fichier : est le nom repris dans le code PHP pour le traitement
Si besoin de passer d’autres valeurs que le FILE, il est possible d’ajout en dessous du commentaire // Ajout de valeur spécifique une ou plusieurs lignes sur le modèle suivant récupérables en POST
input_file_data.append("nom_variable", "Valeur")
HTML modifié
Version évolué du formulaire HTML prévoyant une zone de prévisualisation et une zone de Drag & Drop
<fieldset class="form-group">
<legend class="col-form-label required">Visuels</legend>
<div class="dgwww_zone_upload">
<p class="message">Zone de dépot de fichier</p>
</div>
<input type="file" name="dgwww_zone_preview" id="dgwww_zone_preview" class="dgwww_input_file_upload" data-produit-id="{{ produit_id }}" data-site-id="{{ site_id }}" />
<div class='dgwww_zone_preview'>
<span></span>
</div>
</fieldset>
CSS additional (SCSS)
$dgwww_zone_upload-height:100px;
$dgwww_zone_upload-padding:20px;
.dgwww_zone_upload{
border: 1px solid grey;
max-height: $dgwww_zone_upload-height;
height: $dgwww_zone_upload-height;
line-height: $dgwww_zone_upload-height;
width: auto;
padding: $dgwww_zone_upload-padding;
text-align: center;
cursor: pointer;
p{
line-height:calc(#{$dgwww_zone_upload-height} - (#{$dgwww_zone_upload-padding} * 2));
}
}
.dgwww_input_file_upload{
display: none;
}
.dgwww_zone_preview{
display: grid;
grid-template-columns: 1fr 1fr 1fr;
span{
display: none;
}
img{
height: auto;
max-height: 100px;
width: auto;
max-width: 100px;
margin-top: 15px;
}
}