Explorateur de fichiers

Explorateur de fichiers

Tags : JavaScript, PHP, Tutoriaux, jQuery
Catégorie : Lemon Cake
Mise en ligne : 12 Décembre 2013 à 15:07

Il y a quelques jours je vous parlais d'un petit plugin sympa pour parcourir un dossier et ses sous-dossiers. Le système est très pratique mais je me suis aperçu qu'il comportait une grosse faille de sécurité. En effet, il suffisait de faire une petite injection JavaScript via la console du navigateur et vous aviez accès aux dossiers que vous n'auriez jamais pu voir.

Je me suis alors dis que plutôt que de m'amuser à sécuriser le tout, j'ai recréer un système identique mais cette fois beaucoup plus sécurisé. Et du coup cela fera un tuto pour vous montrer comment parcourir un dossier un PHP.

Prérequis

Pour réaliser cet explorateur de fichiers vous devrez avoir :

  • Un serveur web avec PHP 5 ou supérieur
  • La bibliothèque JavaScript jQuery
  • Et savoir lire (mais bon si vous êtes ici c'est sans doute pas pour les images)

Scan des dossiers

Pour trouver le contenu d'un dossier en PHP, il y a plusieurs solutions. La plus simple est la fonction scandir() mais demande d'avoir PHP5 sur son serveur. Cette fonction s'utilise de la façon suivante :


// On passe en paramètre le dossier à scanner // On récupère le contenu du dossier dans un tableau $files = scandir('./repertoire/');

Création de la fonction de scan

Nous allons passer maintenant à la création de la fonction qui va scanner automatiquement les dossiers et ses sous dossiers.

function scan($dir) {
    // On regarde déjà si le dossier existe
    if(is_dir($dir)) {
        // On le scan et on récupère dans un tableau le nom des fichiers et des dossiers
        $files = scandir($dir);

        // On supprime . et .. qui sont respectivement le dossier courant et le dossier précédent
        unset($files[0], $files[1]);

        // On tri le tableau de façon intéligente (à la façon humaine)
        // http://www.php.net/function.natcasesort
        natcasesort($files);

        // On commence par afficher les dossiers
        foreach($files as $f) {
            // S'il y a un dossier
            if(is_dir($dir.$f)) {
                // On affiche alors les données
                echo '<li class="folder">'.$f.'</li>';
                echo '<ul class="tree">';

                // Et du coup comme c'est un dossier, un le rescan
                scan($dir.$f."/");

                echo '</ul>';
            }
        }

        // Puis on affiche les fichiers
        foreach($files as $f) {
            // S'il y a un fichier
            if(is_file($dir.$f)) {
                echo '<li class="file" rel="'.$dir.$f.'">'.$f.'</li>';
            }
        }
    }
}

La mise en forme

* {
    font-family : 'Arial', sans-serif;
    font-size : 12px;
}

ul {
    list-style : none;
    margin : 0px;
    padding : 0px;
    padding-left : 25px;
}

li {
    padding-left : 20px;
    line-height : 18px;
    cursor : pointer;
}

li.folder {
    background : url("folder.png") no-repeat left center;
}

li.file {
    background : url("file.png") no-repeat left center;
}

Ajoutons un peu d'animation

Pour avoir un peu d'animation on va rajouter quelques lignes de JavaScript

jQuery(function($){
    // On commence par cacher tous les sous dossiers
    $("ul.tree").hide();

    // Lors du click du un dossier
    $("li.folder").click(function () {
        // Si le dossier n'est pas ouvert on l'ouvre, sinon, on le ferme
        $(this).next("ul").toggle("fast");
    });

    // Lors du click sur un fichier
    $("li.file").click(function () {
        // On lance le téléchargement du fichier
        document.location = "dl.php?f="+$(this).attr("rel");
    });
});

Téléchargement des fichiers

Voici un petit script PHP pour télécharger le fichier qu'on lui passera en paramètre

// La fonction end(), permet de récupérer le dernier objet d'un tableau
// http://cz1.php.net/function.end

$file = explode("/", $_GET['f']);

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename(end($file)));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($_GET['f']));
ob_clean();
flush();

readfile($_GET['f']);
exit;

Conclusion

Sa mise en place est relativement simple :

php

Vous pouvez voir une petite démo :

<Laisser un commentaire/>

* Champs obligatoire