PHP - Téléchargement de fichier

Bonjour à tous, futurs développeurs PHP ! Aujourd'hui, nous allons plonger dans un sujet passionnant qui vous permettra d'ajouter une fonctionnalité sympa à vos sites web - le téléchargement de fichiers en utilisant PHP. En tant que votre enseignant bienveillant en informatique, je suis là pour vous guider pas à pas dans cette aventure. Alors, prenez votre boisson favorite, installez-vous confortablement, et c'est parti pour le codage !

PHP - Download File

La fonction readfile()

Au cœur du téléchargement de fichiers en PHP se trouve la fonction readfile(). Cette petite fonction pratique est votre outil de choix lorsque vous souhaitez lire un fichier et écrire son contenu dans le tampon de sortie. Ne vous inquiétez pas si cela semble un peu technique - nous allons le décomposer ensemble !

Utilisation de base

Commençons par un exemple simple :

<?php
readfile("example.txt");
?>

Dans cet extrait de code, readfile() lit le contenu de "example.txt" et le sort directement dans le navigateur. C'est magique - le contenu du fichier apparaît sur votre écran !

Téléchargement de fichiers

Maintenant, c'est là que cela devient intéressant. Nous pouvons utiliser readfile() pour provoquer un téléchargement. Jetons un œil à un exemple plus complet :

<?php
$file = "myfile.pdf";

if(file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
?>

Whaou, c'est beaucoup à ingérer ! Reprenons :

  1. Nous spécifions le fichier que nous voulons télécharger ($file = "myfile.pdf").
  2. Nous vérifions si le fichier existe en utilisant file_exists().
  3. Si oui, nous configurons une série d'en-têtes :
  • Content-Description indique au navigateur qu'il s'agit d'un transfert de fichier.
  • Content-Type définit le type MIME comme un fichier binaire générique.
  • Content-Disposition pousse le navigateur à télécharger le fichier.
  • Les autres en-têtes assurent que le fichier n'est pas mis en cache et est traité correctement.
  1. Enfin, nous utilisons readfile() pour sortir le contenu du fichier.

Types de fichiers courants

Different types de fichiers peuvent nécessiter des en-têtes différents. Voici un tableau pratique des types de fichiers courants et leurs en-têtes Content-Type correspondants :

Type de fichier En-tête Content-Type
PDF application/pdf
ZIP application/zip
JPEG image/jpeg
PNG image/png
MP3 audio/mpeg
MP4 video/mp4

Création d'un lien de téléchargement

Maintenant que nous savons comment déclencher un téléchargement, créons un lien de téléchargement convivial :

<!DOCTYPE html>
<html>
<body>

<h2>Télécharger des fichiers</h2>
<p><a href="download.php?file=myfile.pdf">Télécharger PDF</a></p>

</body>
</html>

Dans ce HTML, nous créons un lien vers un script PHP (download.php) qui gérera le téléchargement du fichier. Nous passons le nom du fichier comme paramètre dans l'URL.

Maintenant, créons le script download.php :

<?php
if(isset($_GET['file'])) {
$file = $_GET['file'];
$filepath = "uploads/" . $file;

if(file_exists($filepath)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($filepath).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($filepath));
readfile($filepath);
exit;
} else {
echo "Fichier non trouvé.";
}
}
?>

Ce script fait ce qui suit :

  1. Vérifie si un paramètre de fichier a été passé dans l'URL.
  2. Construit le chemin complet du fichier (en supposant que les fichiers sont dans un répertoire "uploads").
  3. Si le fichier existe, il configure les en-têtes et déclenche le téléchargement.
  4. Si le fichier n'existe pas, il affiche un message d'erreur.

Considérations de sécurité

Maintenant, je sais ce que vous pensez - "Maisenseignant, n'est-ce pas un peu risqué ? Que se passe-t-il si quelqu'un essaie de télécharger des fichiers qu'il ne devrait pas ?" Excellent pregunta ! Vous avez complètement raison, et c'est pourquoi nous devons parler de sécurité.

Validation des chemins de fichiers

Nous ne devrions jamais faire confiance directement à l'entrée utilisateur. Voici une version améliorée de notre script de téléchargement :

<?php
if(isset($_GET['file'])) {
$file = basename($_GET['file']);
$filepath = "uploads/" . $file;

// Validation du chemin du fichier
$realPath = realpath($filepath);
$uploadDir = realpath("uploads/");

if($realPath === false || strpos($realPath, $uploadDir) !== 0) {
die("Chemin de fichier invalide.");
}

if(file_exists($filepath)) {
// ... (reste du code de téléchargement)
} else {
echo "Fichier non trouvé.";
}
}
?>

Dans cette version :

  1. Nous utilisons basename() pour éliminer toute tentative de traversée de répertoire.
  2. Nous utilisons realpath() pour obtenir le chemin réel du fichier et du répertoire des téléchargements.
  3. Nous vérifions si le chemin réel du fichier commence par le chemin du répertoire des téléchargements, assurant ainsi que nous n'accédons pas à des fichiers en dehors du répertoire prévu.

Conclusion

Et voilà, les amis ! Nous avons traversé le pays des téléchargements de fichiers PHP, depuis les bases de readfile() jusqu'à la création de liens de téléchargement et même touché à quelques considérations de sécurité importantes. Souvenez-vous, avec grand pouvoir vient grande responsabilité - toujours valider l'entrée utilisateur et penser à la sécurité lors des téléchargements de fichiers.

J'espère que vous avez apprécié cette leçon autant que j'ai apprécié l'enseigner. Continuez à pratiquer, continuez à coder, et avant que vous ne vous en rendiez compte, vous serez créer des applications PHP incroyables avec toutes sortes de fonctionnalités de téléchargement sympas. Jusqu'à la prochaine fois, bon codage !

Credits: Image by storyset