PHP - Datei herunterladen

Hallo da draußen, ambitionierte PHP-Entwickler! Heute tauchen wir in ein spannendes Thema ein, das es Ihnen ermöglicht, Ihrer Website einige coole Funktionen hinzuzufügen - das Herunterladen von Dateien mit PHP. Als Ihr freundlicher Nachbarschafts-Computerlehrer bin ich hier, um Sie auf diesem Weg Schritt für Schritt zu führen. Also holen Sie sich Ihr Lieblingsgetränk, machen Sie es sich gemütlich und lassen Sie uns anfangen zu codieren!

PHP - Download File

Die Funktion readfile()

Im Herzen des Datei-Downloads in PHP liegt die Funktion readfile(). Diese kleine, aber feine Funktion ist Ihr gå-to-Werkzeug, wenn Sie eine Datei lesen und deren Inhalt in den Ausgabepuffer schreiben möchten. Machen Sie sich keine Sorgen, wenn das etwas technisch klingt - wir werden es gemeinsam auseinandernehmen!

Grundlegende Verwendung

Lassen Sie uns mit einem einfachen Beispiel beginnen:

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

In diesem Code-Snippet liest readfile() den Inhalt von "example.txt" und gibt ihn direkt an den Browser aus. Es ist wie Magie - der Inhalt der Datei erscheint auf Ihrem Bildschirm!

Dateien herunterladen

Nun, hier wird es interessant. Wir können readfile() verwenden, um einen Datei-Download auszulösen. Sehen wir uns ein vollständigeres Beispiel an:

<?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;
}
?>

Wow, das ist viel auf einmal! Lassen Sie uns das auseinandernehmen:

  1. Wir geben die Datei an, die wir herunterladen möchten ($file = "myfile.pdf").
  2. Wir überprüfen, ob die Datei existiert, indem wir file_exists() verwenden.
  3. Wenn sie existiert, stellen wir eine Reihe von Headerzeilen ein:
  • Content-Description informiert den Browser, dass es sich um eine Dateiübertragung handelt.
  • Content-Type setzt den MIME-Typ auf eine generische Binärdatei.
  • Content-Disposition löst den Download der Datei aus.
  • Die anderen Header sorgen dafür, dass die Datei nicht gecacht wird und korrekt behandelt wird.
  1. Schließlich verwenden wir readfile(), um den Inhalt der Datei auszugeben.

Gemeinsame Dateitypen

Verschiedene Dateitypen können unterschiedliche Header erfordern. Hier ist eine praktische Tabelle mit häufigen Dateitypen und ihren entsprechenden Content-Type-Headerzeilen:

Dateityp Content-Type Header
PDF application/pdf
ZIP application/zip
JPEG image/jpeg
PNG image/png
MP3 audio/mpeg
MP4 video/mp4

Erstellen eines Download-Links

Nun, da wir wissen, wie man einen Download auslöst, lassen Sie uns einen benutzerfreundlichen Download-Link erstellen:

<!DOCTYPE html>
<html>
<body>

<h2>Dateien herunterladen</h2>
<p><a href="download.php?file=myfile.pdf">PDF herunterladen</a></p>

</body>
</html>

In diesem HTML erstellen wir einen Link zu einem PHP-Skript (download.php), das den Datei-Download verarbeitet. Wir übergeben den Dateinamen als Parameter in der URL.

Nun erstellen wir das download.php-Skript:

<?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 "Datei nicht gefunden.";
}
}
?>

Dieses Skript führt folgendes aus:

  1. Überprüft, ob ein Dateiparameter in der URL übergeben wurde.
  2. Konstruiert den vollständigen Dateipfad (unter der Annahme, dass Dateien im Verzeichnis "uploads" gespeichert sind).
  3. Wenn die Datei existiert, stellt es die Headerzeilen ein und löst den Download aus.
  4. Wenn die Datei nicht existiert, zeigt es eine Fehlermeldung an.

Sicherheitsüberlegungen

Nun, ich weiß, was Sie denken - "Aber Lehrer, ist das nicht ein bisschen riskant? Was ist, wenn jemand versucht, Dateien herunterzuladen, die er nicht sollte?" Tolle Frage! Sie haben absolut recht, und das ist der Grund, warum wir über Sicherheit sprechen müssen.

Validieren von Dateipfaden

Wir sollten niemals Benutzereingaben direkt vertrauen. Hier ist eine verbesserte Version unseres Download-Skripts:

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

// Validieren des Dateipfades
$realPath = realpath($filepath);
$uploadDir = realpath("uploads/");

if($realPath === false || strpos($realPath, $uploadDir) !== 0) {
die("Ungültiger Dateipfad.");
}

if(file_exists($filepath)) {
// ... (Rest des Download-Codes)
} else {
echo "Datei nicht gefunden.";
}
}
?>

In dieser Version:

  1. Wir verwenden basename() um jegliche Verzeichnistrukturversuche zu entfernen.
  2. Wir verwenden realpath() um den tatsächlichen Pfad der Datei und des Upload-Verzeichnisses zu erhalten.
  3. Wir überprüfen, ob der tatsächliche Pfad der Datei mit dem Upload-Verzeichnispfad beginnt, um sicherzustellen, dass wir keine Dateien außerhalb des beabsichtigten Verzeichnisses zugreifen.

Schlussfolgerung

Und da haben Sie es, Leute! Wir haben die Welt der PHP-Datei-Downloads durchquert, von den Grundlagen von readfile() bis hin zur Erstellung von Download-Links und haben sogar einige wichtige Sicherheitsüberlegungen angerissen. Erinnern Sie sich daran, dass mit großer Macht auch große Verantwortung kommt - validieren Sie immer Benutzereingaben und denken Sie an Sicherheit, wenn Sie mit Datei-Downloads arbeiten.

Ich hoffe, Sie haben diese Lektion so sehr genossen wie ich es genoß, sie zu unterrichten. Üben Sie weiter, codieren Sie weiter, und bevor Sie es wissen, werden Sie erstaunliche PHP-Anwendungen mit allen möglichen coolen Download-Funktionen erstellen. Bis下次, fröhliches Coden!

Credits: Image by storyset