Falconbyte unterstüzen
Betrieb und Pflege von Falconbyte brauchen viel Zeit und Geld. Um dir auch weiterhin hochwertigen Content anbieten zu können, kannst du uns sehr gerne mit einem kleinen "Trinkgeld" unterstützen.
Thema in Kurzform
// HTML-Formular
<form action="upload.php" method="post" enctype="multipart/form-data">
<p>Datei auswählen:</p>
<p><input type="file" name="datei"></p>
<p><input type="submit" value="Hochladen!" name="submit"></p>
</form>
// Datei in Verzeichnis "uploads" auf Server speichern
move_uploaded_file($_FILES["datei"]["tmp_name"], "uploads/".$_FILES["datei"]["name"]);
Vorbemerkungen
Mit PHP können wir den Besuchern unserer Website einen komfortablen Datei-Upload ermöglichen. Damit wird das Hochladen eines eigenen Profilbildes oder die Rückmeldung in Form eines pdf-Dokuments zur Selbstverständlichkeit.
Allerdings ist der Datei-Upload immer auch mit Risiken für Website-Betreiber verbunden, da ihn Angreifer ausnutzen können, um Schadsoftware einzuschleusen. Wir zeigen weiter unten, wie wir dieses Risiko reduzieren können.
HTML-Upload-Formular erstellen
Damit Nutzer unserer Website Dateien hochladen können, benötigen wir zunächst ein entsprechendes HTML-Formular. Wir schreiben dieses in eine Datei namens "formular.html":
<!DOCTYPE html><html><body>
<form action="upload.php" method="post" enctype="multipart/form-data">
<p>Datei auswählen: <input type="file" name="datei">
</p>
<p>
<input type="submit" value="Hochladen!" name="submit">
</p>
</form >
</body></html>
Ein paar Erläuterungen zum Formular:
- Das Formular muss mit POST versendet werden.
- Außerdem ist Form-Attribut enctype="multipart/form-data" erforderlich. Es legt fest die Art der Daten fest, die beim Absenden des Formulars verwendet werden.
- Das Formularfeld <input type="file"> stellt dem Anwender einen Dateibrowser bereit, mit dem er die hochzuladende Datei auf seinem System auswählen kann.
- Das Formular sendet die Daten schließlich an die Zieldatei namens "upload.php". Hier erfolgt die Verarbeitung der hochgeladenen Datei.
Das Formular sieht dann so aus:
Beim Klick auf "Datei auswählen" öffnet sich der Datei-Browser zum Auswahl der hochzuladenden Datei.
Das $_FILES Array
Die durch das Formular an den Server gesendete Datei kann mit dem superglobalen Array $_FILES erreicht werden:
$_FILES["datei"]["tmp_name"] | speichert den temporären Namen der Datei auf dem Server |
$_FILES["datei"]["name"] | speichert den Original-Dateinamen auf dem System des Anwenders |
$_FILES["datei"]["size"] | speichert die Dateigröße der hochgeladenen Datei in Bytes |
$_FILES["datei"]["type"] | speichert den Typ der Datei |
In der Zieldatei upload.php können wir die einzelnen Array-Elemente ausprobieren:
<?php
echo $_FILES["datei"]["tmp_name"] . "<br>";
echo $_FILES["datei"]["name"] . "<br>";
echo $_FILES["datei"]["size"] . "<br>";
echo $_FILES["datei"]["type"] . "<br>";
?>
Beim Upload einer jpg-Datei namens "dracula.jpg" bekommen wir so im Browserfenster Informationen zur Datei angezeigt:
Uploads auf Server speichern
Übertragene Dateien werden nur temporär gespeichert. Das sehen wir am temporären Pfad ("temp") und dem temporären Dateinamen. Die Datei wird automatisch wieder gelöscht, wenn das PHP-Skript zum Ende gekommen ist.
Wir müssen uns deshalb selbst darum kümmern, die hochgeladene Datei "aufzufangen" und dorthin zu speichern, wo wir sie weiterverwenden können.
Zielordner erstellen
Erstellen wir zunächst einen neuen Ordner auf dem Webspace, z.B. "uploads" (dieser befindet sich im gleichen Verzeichnis wie unser PHP-Skript). Nach dorthin sollen die hochgeladenen Dateien aus dem temporären Verzeichnis verschoben und dauerhaft gespeichert werden. Vergessen wir auch nicht, dass dieser Ordner Schreibrechte (CHMOD 777) benötigt.
move_uploaded_file()
Um eine hochgeladene Datei in unseren "uploads"-Ordner zu verschieben, stellt PHP die Funktion move_uploaded_file() bereit.
Die Funktion benötigt zwei Parameter: Den Dateinamen der hochgeladenen Datei sowie das Ziel der Verschiebung.
In unserem PHP-Skript in der Datei "upload.php" sieht das dann so aus:
move_uploaded_file($_FILES["datei"]["tmp_name"], "uploads/".$_FILES["datei"]["name"]);
Existiert eine Datei mit selben Namen schon, wird sie überschrieben.
Die hochgeladene Datei ist nun dauerhaft gespeichert und kann über die URL aufgerufen werden:
Sicherheit bei Uploads
Ohne Sicherheitsmechanismen sollten wir Datei-Uploads niemals zur Verfügung stellen. Zu groß ist die Gefahr, dass Angreifer das Formular missbrauchen, um Schaden anzurichten.
Einige schnell einzubauende Schutzmaßnahmen sollten sein:
Maximale Dateigröße anpassen
Wir sollten unbedingt die Dateigröße (in Bytes) der Uploads beschränken. Dies gelingt uns mithilfe des Array-Elements $_FILES["datei"]["size"].
if($_FILES["datei"]["size"] > 500000) {
echo "Sorry, diese Datei ist zu groß!";
}
Nur bestimmte Dateitypen zulassen
Wenn Nutzer ein Profilbild hochladen sollen, ergeben nur Bilddateien (jpg, jpeg, png, gif) Sinn. Alle anderen Dateitypen sollen gesperrt werden:
$datei = $_FILES["datei"]["name"];
$dateityp = strtolower(pathinfo($datei, PATHINFO_EXTENSION));
// Prüfe Dateityp
if($dateityp != "jpg" &&
$dateityp != "png" &&
$dateityp != "jpeg" &&
$dateityp != "gif" ){
echo "Sorry, nur JPG, JPEG, PNG & GIF Dateien sind erlaubt!";
}
Existierende Datei nicht überschreiben
Mit der Funktion file_exists() kann geprüft werden, ob eine Datei mit gleichlautendem Dateinamen schon auf dem Server existiert. Diese soll dann nicht überschrieben werden:
$datei = "uploads/" . $_FILES["datei"]["name"];
// Prüfe, ob Datei schon existiert:
if (file_exists($datei)) {
echo "Sorry, Datei mit gleichen Namen schon vorhanden!";
}
file_exists() benötigt den relativen Pfad der Datei. Darum stellen wir das Verzeichnis "uploads/" voran.
Fertiges Skript
Nun das vollständige PHP-Skript für den Datei-Upload von Bild-Dateien:
<?php
$datei = "uploads/" . $_FILES["datei"]["name"];
$dateityp = strtolower(pathinfo($datei, PATHINFO_EXTENSION));
$uploadOK = TRUE;
//Dateigröße prüfen
if($_FILES["datei"]["size"] > 500000) {
echo "Sorry, diese Datei ist zu groß!";
$uploadOK = FALSE;
}
// Prüfe Dateityp
if($dateityp != "jpg" && $dateityp != "png" && $dateityp != "jpeg" && $dateityp != "gif" ) {
echo "Sorry, nur JPG, JPEG, PNG & GIF Dateien sind erlaubt!";
$uploadOK = FALSE;
}
// Prüfe, ob Datei schon existiert:
if (file_exists($datei)) {
echo "Sorry, Datei mit gleichen Namen schon vorhanden!";
$uploadOK = FALSE;
}
// Datei-Upload erlauben und in uploads-Ordner verschieben
if($uploadOK){
move_uploaded_file($_FILES["datei"]["tmp_name"], "uploads/".$_FILES["datei"]["name"]);
echo " Der Upload war erfolgreich!";
}
?>
Übungen
einfach
Welche PHP-Funktion verschiebt den temporären Dateiupload in einen dauerhaften Standort? Welche Sicherheitsvorkehrungen sollten auf jeden Fall damit verbunden sein?
mittel
Wie viele Fehler sind im folgenden Programm vorhanden?
<form action="upload.php" method="get" enctype="multipart/form-data">
<p>Datei auswählen:</p>
<p><input type="file" name="datei"></p>
<p><input type="submit" value="Hochladen!" name="submit"></p>
</form >
// weiterer Code...
move_uploaded_file($_FILES["file"]["tmp_name"], "uploads/".$_FILES["file"]["name"]);
// weiterer Code...
A. 1
B. 2
C. 3
D. keine Fehler!
schwer
Schauen Sie mal, die Eulen:
Knuffig, oder? Aber jetzt wird's ernst!
Erstellen Sie ein Formular für Bild-Uploads. Die Datei-Pfade der auf den Server hochgeladenen Bilder sollen in einer txt-Datei gespeichert werden.
Alle hochgeladenen Bilder sollen übrigens auch wirklich am Bildschirm angezeigt werden.
Das Ganze soll sich in einer einzelnen PHP-Datei abspielen.
Hier die einzelnen Eulen-Bilder zum Download (rechte Maustase -> Ziel speichern unter...).