PHP: Upload von Dateien (Bilder, PDF & Co.) mit $_FILES

Wer kennt es nicht, man meldet sich in einem Portal an, man gibt sich einen Nutzernamen und lädt ein Profilbild hoch. Wie das funktioniert das Hochladen von Dateien ((PHP) Upload) und welche Technik steckt dahinter ?

Die hochzuladenden Dateien (wie ein Profilbild) werden von dem Browser (Firefox, Chrome, Safari, Edge etc.) im Content einer HTTP Anfrage an den Webserver der entsprechenden Webseite gesendet. Die HTTP Anfrage wird von dem Webserver verarbeitet und z.B. an die Scriptsprache PHP weitergeleitet. PHP verarbeitet mit $_POST und $_FILES die empfangene Anfrage und stellt sie dem Programm bereit.

Ein Webserver funktioniert grundsätzlich wie der Computer; die empfangenden Dateien werden in irgendeinem Ordner-System ablegt.

Upload einer einzelnen Datei

Für den Upload einer Datei benötigen wir ein HTML-Formular.

Einfaches HTML Formular zum hochladen einer Datei

Das Formular ist erstmal relativ einfach, uns interessiert die Technik dahinter. Sobald man den Button „Durchsuchen…“ klickt, wird der Dateibrowser mit der Dateiauswahl geöffnet.

Wichtig ist, dass das Formular im Form-Tag enctype="multipart/form-data  enthält, sonst können keine Dateien hochgeladen werden. In folgenden Schritt erweitern wir unser Script mit PHP, so dass die Werte (Dateigröße, Dateiformat) der hochgeladenen angezeigt werden.

<input name="datei" type="file" /> Der Input-Tag ermöglicht das Hochladen (Upload) einer Datei.

Zum Nachmachen verwendet ihr am Besten das freie Programm xampp als Webserver und legt im Verzeichnis htdocs einen neuen Ordner „upload“ an. In dem Ordner „upload“ legt ihr die Datei „index.php“ an und speichert den Code für das Formular in der Datei.

XAMPP htdocs Verzeichnis

PHP: Upload einer Datei

Die große Magie passiert durch die Verarbeitung der empfangen Datei durch die Scriptsprache PHP.

Nach dem Senden einer Datei wird folgendes angezeigt.

Details einer Datei von $_FILES

Der Name des Input-Feldes wird uns als Name für das Array wiedergegeben, wir erfahren den Dateinamen [name], Dateityp [type], Dateigröße [size], Fehler [error] und dem temporären Dateinamen [tmp_name]. Den temporären Dateinamen benötigen wir zum Speichern der Datei auf unserem Webserver (Webspace). Hierzu legen wir auf dem Webserver im Verzeichnis der index.php ein neues Verzeichnis namens „uploads“ an.

Upload-Verzeichnis in XAMPP

Den Quelltext unseres PHP Upload-Scripts erweitern wir ebenfalls um wenige Zeilen, so dass die Datei gespeichert wird (und Bilder direkt angezeigt werden). Wichtig ist die interne PHP Funktion move_uploaded_file(temporäre Dateiname, neuer Dateiname) , hier passiert die ganze Magie des Speicherns auf dem Webspace. Auf dem Webserver wird die hochgeladene temporäre Datei durch die PHP Funktion verschoben und gespeichert.

Nach dem Absenden wird die Datei und Formular angezeigt, sofern es ein Bild ist.

Die hochgeladenen Dateien werden nun im Verzeichnis „uploads“ abgelegt und verfügbar gemacht.

Hochgeladene Datei im Upload-Verzeichnis

Zusehen ist die hochgeladene Datei auf dem Webserver.

Upload von Dateien (mehreren Dateien)

Das Hochladen von mehreren Dateien gleichzeitig gestaltet sich im Anschluss nicht mehr schwer. Dennoch müssen wir den Quellcode an verschiedenen Stellen ändern.

Die Zeile <input name="datei" type="file" value="" /> aus dem obigen Beispiel für eine einzelne Datei erweitern wir einfach zu <input name="datei[]" type="file" value="" multiple /> . $_FILES enthält jetzt ein Array mit den Dateien, welcher über eine FOR-Schleife angesprochen werden können.

Testet es einfach selbst =).

Hochladen von nur zum Beispiel Bildern

Für ein Portal möchte man zum Beispiel das nur gewissen Datei-Typen wie Bilder hochgeladen werden dürfen. Dies kann man mit der Angabe von accept="image/*" oder accept=".png, .jpg, .jpeg"   im Input-File-Tag erreichen, jedoch sollte auch im PHP Script eine Prüfung der Dateitypen (Dateiformate) erfolgen. Ich würde daher die zweite Variante empfehlen, so dass der Dateiname mit der PHP-Funktion in_array geprüft werden kann. Bitte studiert das folgenden Quellcode-Beispiel.

Der Explorer bietet zum Hochladen durch accept=“*“ die folgenden Dateiendungen (Formate) an.

Eine Prüfung des Dateiformats (*.jpg, *.png, *.gif) ist nötig, da nicht alle Browser die Auswahl von bestimmten Dateien implementiert haben oder unterstützen. Weiterhin versuchen Hacker auf anderen Wegen, Viren einzuschleusen.

Zum Testen des Dateinamenfilters (Dateiendungen) lasst ihr die Angabe von accept=“*“ im Input-Tag einfach weg.

PHP Upload Einstellungen (bekannte Fehler)

Gerade beim Lernen einer Programmiersprache steckt der Fehlerteufel oft im Detail, so bei PHP auch. Es hilft positiv zu bleiben, wir haben alle mal klein angefangen und habe mit der Zeit das Wissen erworben.

Gerade bei dem Hochladen von Dateien, Dokumenten und Bilder ist daran zu denken, das die Dateigröße vom Server angenommen wird und verarbeitet werden kann. Mir der in PHP eingebauten Funktion phpinfo();  kann man sich Konfigurationsdetails des Servers anschauen. Im Folgenden möchte ich mit euch im Bezug des PHP Uploads genauer darauf eingehen.

Direkte Einstellungen für Dateien (Files) in der php.ini

file_uploads=On  Erlaubt dem Server das Annehmen der gesendeten Dateien.

upload_tmp_dir="C:\xampp\tmp"  Die Hochgeladenen Dateien werden hier zwischen gespeichert und können mit der Funktion move_uploaded_file($tmp_datei_name, $neuer_datei_name)  in einem Verzeichnis des Webspaces (Webhost) gespeichert werden.

upload_max_filesize=40M  Gibt gesamte Dateigröße an, für alle Dateien welche gemeinsam hochgeladen werden dürfen.

max_file_uploads=20  Anzahl der Dateien welche gemeinsam mit einem Upload gemeinsam Hochgeladen werden dürfen.

Indirekte Einstellungen für Dateien (Files) in der php.ini

memory_limit=512M  Gibt die maximale Script-Größe, welche durch den Server verarbeitet werden dürfen – hierzu zählen auch die hochzuladenden Dateien.

max_execution_time=120  Maximale Ausführungszeit in Sekunden, gerade bei größeren PHP-Anwendungen wo zum Beispiel die Systeme eigenständige Updates durchführen sollte dieser Wert angemessen hoch sein.

Hinweise

Der verwendete PHP-Code sollte natürlich nicht in einer Produktivumgebung verwendet werden. In einer Produktivumgebung sollten die abgelegten Dateien durch „kryptische“ Dateinamen (z.B. Hashs) vor unerlaubten Downloads geschützt werden.

Vor dem Speichern sollte geprüft werden, ob eine Datei auf dem Webserver bereits existiert, damit diese nicht überschrieben wird.

Der Dateiname sollte UNIX konform sein, sodass es keine Probleme mit der URL gibt, hierzu kann z.B. die PHP-Funktion urlencode() verwendet werden.

Weitere Informationen (externe Links):