Anthony HERVÉ

Ingénieur édudes et développement

PHP Upload et progress

12/12/2016
Image actualité

Bonjour tout le monde,

 

Aujoud'hui, petit article consacré à l'upload de fichiers. Sujet pas évident qui revient tout le temps sur le tapis. Pour ma part, je travaillais sur une sorte de Google Drive simplifié et pour ce projet je cherchais une solution personnalisable pour l'upload multiple de fichiers. Mon but était également d'avoir une vision de l'avancement des uploads.

 

Après avoir cherché un peu sur Google, j'ai enfin trouvé la solution qui me convenait. Voici donc ma solution (qui est loin d'être la seule et cetainement pas la meilleure).

Répertoire de travail

  • index.php : fichier HTML/PHP de base avec un input pour sélectionner des fichiers et un bouton pour les uploader
  • upload.js : fichier javascript avec les fonctions nécessaires pour l'upload
  • upload.php : fichier appelé pour l'import des fichier
  • dossier files : dossier de réception des fichiers chargés

Upload avec sélection

Côté HTML

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Upload</title>
        <script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
        <script src="upload.js"></script>
    </head>
    <body>
        <h1>Upload multiple files</h1>
        <div>
            <input type="file" id="files" name="files[]" multiple/>
            <button class="btn-upload">Upload</button>
        </div>
        <!-- For progress bars -->
        <div class="progress"></div>
        <!-- For upload results -->
        <div id="result"></div>
    </body>
</html>

Côté Javascript

$(function () {

    /**
     * Function called to upload one file.
     * @param file
     * @param item
     */
    function uploadFile(file, item) {
        // Add progress bar
        $('.progress').show();
        $('.progress').append(file.name + ' : <progress class="progress-' + item + '" value="0" max="100"></progress>');

        // Create object XMLHttpRequest
        var request = new XMLHttpRequest();

        // Event progress to change value of progress bar
        request.upload.addEventListener('progress', function (e) {
            $('.progress-' + item).css('display', 'block');
            var value = Math.round((e.loaded / e.total) * 100);
            $('.progress-' + item).attr("value", value);
        }, false);

        // Create object FormData
        var formData = new FormData();
        // Add file to FormData
        formData.append('file', file);
        // File to call
        request.open('post', 'upload.php');
        // Function called when request ended
        request.onload = function (e) {
            $('#result').append(request.response);
        };
        // Send request
        request.send(formData);
    }

    /**
     * Function called to upload files.
     */
    function upload() {
        // Get files
        var files = $('#files')[0].files;
        // Upload file by file
        for (var i = 0; i < files.length; i++) {
            uploadFile(files[i], i);
        }
    }

    // Event click on button Upload
    $('.btn-upload').on('click', upload);
});

Côté PHP

<?php

$uploaddir = 'files/';
$uploadfile = $uploaddir . basename($_FILES['file']['name']);

echo '<pre>';
if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile)) {
    echo "Le fichier est valide, et a été téléchargé avec succès.\n";
} else {
    echo "Problème lors de l'upload du fichier.\n";
}

echo 'Voici quelques informations sur le fichier :';
print_r($_FILES);

echo '</pre>';

Drag and drop

Maintenant que l'upload "simple" fonctionne bien. Je vous donne quelques clés pour faire la même chose avec l'action de drag and drop (glisser/déposer) de fichier.

  • Ajouter une div dans le fichier index.php
<div id="dropzone">
    Drag and drop your files here
</div>
  • Ajouter des fonctions dans le fichier upload.js
/**
 * Function called when mouse go out dropzone.
 * @param event
 */
function handleDragLeave(event) {
    event.stopPropagation();
    event.preventDefault();
    $('#dropzone').removeClass('draggable');
}

/**
 * Function called when files are dropped in dropzone.
 * @param event
 */
function handleDrop(event) {
    event.stopPropagation();
    event.preventDefault();
    $('#dropzone').removeClass('draggable');
    // Get dropped files
    var files = event.dataTransfer.files;
    for (var i = 0, f; f = files[i]; i++) {
        uploadFile(f, i);
    }
}

/**
 * Function called when mouse go in dropzone.
 * @param event
 */
function handleDragOver(event) {
    event.stopPropagation();
    event.preventDefault();
    $('#dropzone').addClass('draggable');
    event.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
}
  • Ajouter les événements nécessaires dans le fichier upload.js pour lier la dropzone et les fonctions javascript
// Drag and drop
var dropZone = document.getElementById('dropzone');
dropZone.addEventListener('drop', handleDrop, false);
dropZone.addEventListener('dragleave', handleDragLeave, false);
dropZone.addEventListener('dragover', handleDragOver, false);

 

Je vous laisse compléter par un petit peu de style CSS et le tour est joué.

Vous avez maintenant tout ce qu'il faut pour réaliser des uploads de fichiers.

 

A bientôt.

php

Commentaires