Dans plusieurs cas, ça peut être intéressant de contrôler le téléchargement d'une ressource hébergée sur le serveur à l'aide d'un fichier PHP, plus particulièrement s'il est stocké en dehors de la zone publique accessible par le serveur web. Par exemple, si une boutique en ligne doit attendre la réception d'un paiement pour rendre disponible l'accès limité à un fichier en téléchargement, on pourra le faire en utilisant le streaming.
Imaginez qu'on reçoive par $_GET un identificateur unique représentant le fichier, qu'une requête SQL vérifie si l'utilisateur connecté (par la session) peut télécharger le document, tout ce qu'il restera à faire sera de diffuser son contenu.
Le fichier pourrait être hébergé dans un répertoire non accessible par le serveur. Seul le code PHP connaîtrait l'emplacement où le récupérer. Le nom sur le disque pourra aussi différer du nom qu'on voudra présenter au visiteur.
Par exemple, vous vendez vos créations musicales en format mp3 :
// download.php
set_time_limit(0);
$filePath = '/chemin/sur/le/serveur/Track-01.mp3';
$newName = 'Artiste-Album-01-Titre.mp3';
header('Content-Type: audio/mpeg');
header('Content-Disposition: attachment; filename="' . $newName . '";');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($filePath) );
@readfile($filePath) or die('Echec...');
- Le content-disposition "attachment" indique au fureteur qu'il faudra faire afficher la fenêtre "Enregistrer sous" et proposera le nom indiqué dans la variable $newName.
- La fonction filesize() s'assurera d'initialiser l'entête content-length à la taille réelle du fichier.
- @readfile or die : on pourrait mieux controler la lecture du contenu du fichier, en vérifiant d'abord s'il existe avec la fonction file_exists().
- En indiquant set_time_limit(0), on spécifie au serveur qu'il devra diffuser sans interruption. Ceci n'est pas recommandé, il est préférable d'indiquer un temps plus approprié.
<a href="download.php?track=1">Télécharger la première pièce</a>Une autre façon d'utiliser ce script est dans la source d'une balise IMG (évidemment, à condition que le fichier diffusé soit un type compatible). Le fichier download.php récupérerait une image et la diffuserait en tant que source, comme si on avait spécifié <img src="image.png" />. Dans ce cas-ci, on aura qu'à remplacer le content-disposition "attachment" par "inline".
<img src="download.php?file-id=100" />