blur_on
Téléchargement de fichiers en PHP

En résumé :

Cette page a pour but de montrer par l'exemple, comment proposer le téléchargement de fichiers contenus dans un répertoire.

Ce dernier se nomme "ficdir", et contient les fichiers dont le nom, date, adresse, poids... seront ajoutés automatiquement, sous forme de tableau.
Parmi ces informations, figureront la date de dernière modification et le poids de chaque fichier.
Un bouton figure aussi sur la ligne.

Le bouton "Télécharger" est de type "submit", et pour chaque ligne, le script PHP génère un formulaire indépendant (balise <form>).
In fine, on crée un tableau regroupant l'ensemble des fichiers proposés en téléchargement.
Ce tableau va bien sûr s'agrandir au fur et à mesure, dynamiquement, pour chaque fichier ajouté.

Dans l'exemple, l'extension des fichiers proposés en download sont de type *.mp? (mp3, mp4,...)

Langages utilisés : HTML, css, php.


exemple de tableau

La mise en forme (css) intégrée au fichier index.php est évidemment facultative.

Un fichier log (fichierlog.log) enregistre chacun des clics (submit), et potententiellement chaque téléchargement de fichier, bien que rien ne vient confirmer son tranfert intégral.
En effet, l'annulation du téléchargement avant son terme n'est pas pris en compte dans le log.

Aperçu de l'aborescence :

Aborescence

info_outline Attention : dans le fichier "index.php", la ligne : foreach(glob("*.mp?") as $elem)
fait référence à des fichiers dont l'extension est de type mp?, soit mp3, mp4,... il faut bien sûr l'adapter à votre situation.

index.php
    
<!DOCTYPE html>
<html lang="fr">

<head>
    <title>T</title>
    <meta charset="UTF-8">
    <style type="text/css">
    
    
        body{
            background-color: #ccc;
        }
        table {
            font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif;
            background-color: #555;
            border-radius : 5px;
        }
        table td{
            font-size: small;
            background-color: #fdf8f6;
            border-radius: 5px;
        }
        table td:nth-child(2n) {
            
            background-color: #fdf8f6;
            padding: 2px 12px 2px 4px;
            border: 0px solid gray;
            border-radius: 5px;
        }
        table td:nth-child(3n+1) {
            font-size: smaller;
            background-color: #f0f8f6;
            padding: 2px 8px 2px 8px;
            border: 1px solid lightgrey;
            border-radius: 5px;
        }
        .spandl {
            color : #22A2F1;
            font-size: 0.9rem;
            margin-left: 1em;
        }

	.spanb::before {
	    /*content: "&#128073"; */
	    color: pink;
   	    letter-spacing: 6px;
	}
	.spanb::after {
	    /*content: "&#128073"; */
	    color: pink;
	    letter-spacing: 6px;
	}
    

    </style>
</head>
<body>
<h1>Transferts de fichiers - exemple</h1>
<h3>&copy; Peppa & Georges Production 2024</h3>



<?php
$directory="ficdir";
$files = scandir($directory);
//echo $files[3];   //test
$cpt_dl = 0; // compteur qui va référencer la ligne du tableau correspondant à l'URL de téléchargement
chdir($directory); // on se déplace dans le dossier "ficdir"
//echo $directory.getcwd();
$i=0;
foreach(glob("*.mp?") as $elem) { // Pour chaque fichier dont l'extension correspond au masque (pattern) *.mp?

	$dl[]=$elem; // chaque fichier .mp* remplit un tableau "dl"
//    echo "<script>console.log('".$dl[$i]."')</script>";
    $i++;
}

echo "<table>";
chdir('../'); // on revient un niveau au-dessus, là où se situent les fichiers php

foreach ($dl as $file) { // pour chaque fichier (dont le nom est contenu dans le tableau dl)
    
    $file_path = $directory . '/' . $file;

    if (is_file($file_path)) {
        echo "<tr><td>";
        echo date('F d Y',filemtime($file_path))."</td><td>";
        echo $file_path;
        echo "</td>";
        echo "<div class='dlClass'>";
        echo "<form method=\"get\" action=\"download.php\" target=\"_self\">";
        echo "<td>&rArr; ".number_format(filesize($file_path)/1048576,0,',',' ')." Mo </td>"; // 1048576 = 1024*1024
        echo "<td><span class='spanb'>&#128073;&nbsp;<input type=\"submit\" name='dl_sub' value=\"Télécharger\">&nbsp;&#128072;</span>";
        echo "<span class='spandl'>".$file."</span></td>";
        //echo "<script>console.log('file:  ".$file."')</script>";
        echo "<input type=\"hidden\" name='fileValue' value=\"".$file."\">";
        echo "<input type=\"hidden\" name='filePathValue' value=\"".$file_path."\">";
        //echo "<script>console.log('filePathValue:  ".$file_path."')</script>";
        echo "</form>";
        echo "</div>";
        $cpt_dl++;
    }
    echo "</td></tr>";
    if (isset($size)){
        echo "Size : ".$size;
    }
}
echo "</table>";
?>


</body>
</html>


download.php

        
            $f1 = $_GET['fileValue']; // on récupère le nom du fichier passé par le formulaire, méthode get
            $f2 = $_GET['filePathValue']; // idem pour le chemin relatif du fichier (URL locale sur le serveur)
            $size = filesize($f2); // taille du fichier 
            $chemin_courant = getcwd(); 
            
            header('Content-Description: File Transfer');
            header('Content-Type: application/octet-stream');
            header('Content-Disposition: attachment; filename='.$f1); 
            header('Content-Length: '.$size);
            
            // =============================== Alimente (append) le fichier log quand clic sur téléchargement

            // initialisation d'une variable de type "DateTime" pour ajouter la date à chaque ligne de fichier log
            date_default_timezone_set('UTC');
            $logdate = new DateTimeImmutable();
            $logdate = $logdate->format('dmy-H:i');

            echo "<script>console.log(\"logdate : \",".$logdate.")</script>"; // debug
            
            if (!is_file("fichierlog.log")){ // si le fichier n'existe pas
                $myFile = fopen("fichierlog.log","c+"); // on ouvre le fichier en mode création
                }
            else {
                $myFile = fopen("fichierlog.log","a"); // on ouvre le fichier en mode append
            }
            $txt = file_get_contents("fichierlog.log"); // on récupère l'ancien contenu du fichier dans la variable $txt
            $txt .= $logdate.",".$f2; // on y ajoute une nouvelle ligne
            $txt .= PHP_EOL; // retour à la ligne
            
            file_put_contents("fichierlog.log", $txt); // on ajoute cette ligne dans le fichier
            fclose($myFile);
            // ====================================
            
            ob_clean(); // nettoyage du tampon de sortie actif
            flush(); // vide les entêtes et le contenu des tampons
            readfile($f2); //Absolute URL	- Readfile() lit un fichier et l'envoie dans le buffer de sortie.