Teil von SELFHTML aktuell Teil von Artikel Teil von PHP

Dateiupload und Überprüfung mit PHP

nach unten Ludwig Ruderstaller
nach unten Einleitung
nach unten Das Formular
nach unten Struktur der PHP Seite
nach unten Das Formular wurde gesendet
nach unten Weitere Informationen

Ludwig Ruderstaller

E-Mail: E-Mail ruderstaller@dillerpartner.at
Homepage-URL: deutschsprachig http://www.dillerpartner.at/

Bei Fragen zu diesem Beitrag bitte den Autor des Beitrags kontaktieren!

nach obennach unten

Einleitung

Irgendwann kommt man in die Notwendigkeit, den User eine Datei auf den Server übertragen zu lassen. Eben einen File-Upload zu realisieren. Mit PHP geht das relativ einfach, wobei man aber die Sicherheit nicht außer acht lassen sollte.

Dieser Artikel versucht, die Grundlagen zum File-Upload und die notwendigen Funktionen zum Überprüfen der Daten zu vermitteln.

Beachten Sie:

Frühere Versionen dieses Artikels haben sich auf die Konfigurationseinstellung register_globals=on verlassen. PHP empfiehlt, diese Option abzuschalten und wird so auch auf vielen Webservern betrieben.

nach obennach unten

Das Formular

Aus HTML-Sicht sieht ein File-Upload etwa so wie im folgenden Beispiel aus.

Beispiel:

<form enctype="multipart/form-data" action="<?php echo htmlspecialchars ($_SERVER['PHP_SELF']); ?>" method="post">
<input type="hidden" name="max_file_size" value="1000">
file senden: <input name="thefile" type="file">
<input type="submit" value="senden">
</form>

Erläuterung:

Code Bedeutung
enctype="multipart/form-data" Der enctype ist sehr wichtig, ohne ihn funktioniert kein File-Upload. (wenn die method="post" ist und kein enctype gesetzt ist, lautet er standardmäßig application/x-www-form-urlencoded)
action="<?php echo htmlspecialchars ($_SERVER['PHP_SELF']); ?>" Die PHP-Variable $_SERVER['PHP_SELF'] enthält den Namen (+ evtl. Pfad) des aktuellen Dokumentes. Selbstverständlich kann auch ein eigener Name angegeben werden. Sollte wie hier $_SERVER['PHP_SELF'] verwendet werden, so muss auf jeden Fall htmlspecialchars angewendet werden, da die Variable unter bestimmten Umständen mit Daten von der Clientseite gefüllt werden kann und daher nicht vertrauenswürdig ist!
<input type="hidden" name="max_file_size" value="1000"> Dieses Input-Feld teilt dem Browser mit, wie groß ein File maximal sein darf. Aber da dieser Wert von der Clientseite kommt, sollte man nicht zu stark darauf vertrauen!
<input name="thefile" type="file"> Mit diesen Formularfeld wird schließlich der "Dateisystem - Auswahl - Button" angezeigt, mit dem der User ein File von seiner lokalen Festplatte auswählen kann.

nach obennach unten

Struktur der PHP Seite

Im allgemeinen macht es wenig Sinn, das Formular und die PHP-Seite als getrennte Seite zu handhaben.

Folgende Struktur hat sich bewährt:

Schema:

<html>
<!-- Der Kopf der HTML seite inkl evt. layout //-->

<?php
if(isset($_POST['submit']) && $_POST['submit']=="Senden"){
 // Das Formular wurde gesendet
}else{
 // Das Formular muss angezeigt werden
?>
<!-- Das Formular //-->
<?php ?>

nach obennach unten

Das Formular wurde gesendet

PHP stellt uns freundlicherweise einige Variablen zur Verfügung, die uns das Arbeiten mit dem File des Users erleichtern.

Beachten Sie hierbei, dass normale Formularfelder des Dateiabsendeformulars in $_POST landen, während alle Dateiuploadfelder in das Array $_FILES geschrieben werden. Das Array enthält diverse Dateiinformationen in den Feldern des Arrays:

Variable Bedeutung
$_FILES['thefile']['tmp_name'] Pfad und Name der temporären Datei, wie sie im Filesystem des Servers zu finden ist (meistens in der Form /tmp/php234lksdaflk) - diese Datei wird am Skriptende wieder gelöscht.
$_FILES['thefile']['name'] Der Name der Datei, wie sie auf dem Clientsystem genannt wurde. Eventuelle Verzeichnisangaben werden nicht mitgesendet.
$_FILES['thefile']['size'] Die Größe der Datei in Bytes
$_FILES['thefile']['type'] Der Mime-Type der Datei, wie der Client sie lieferte (z.B. image/gif).

Die hochgeladene Datei ist nur solange "existent" wie das Skript läuft. Das heißt, um das File auch für spätere Zugriffe haltbar zu machen, muß es kopiert bzw. verschoben werden.

Normalerweise kann das File überall dorthin kopiert werden wo der Apache-Prozeß Schreibrechte besitzt. Ist allerdings der Safe_Mode aktiv, kann man das File nur in Verzeichnisse schreiben, welche die selbe UID wie der Apache Prozess haben.

Überprüfung der Datei:

Das schönste Upload-Skript nützt nichts, wenn man nicht weiß, um welche Art von Datei es sich handelt.

Ich verwende normalerweise je nach erwartetem Filetype zwei verschiedene Wege der Dateiüberprüfung:

Wenn es sich um Bilder in den Format *.jpg oder *.gif handelt, verwende ich normalerweise die Funktion getimagesize(), die einen Array mit Informationen zurückliefert. Wenn man beispielsweise notiert: $size=getimagesize($_FILES['thefile']['tmp_name']);, dann hat man anschließend folgende Informationen:
$size[0] = Breite der Grafik,
$size[1] = Höhe der Grafik,
$size[2] = Typ der Grafik (wobei: 1 = GIF, 2 = JPG, 3 = PNG, 4 = SWF),
$size[3] = Breite und Höhe der Grafik als String "width=[...] height=[...]".

Siehe dazu auch:

deutschsprachige Seite Funktionsbeschreibung getimagesize() auf php.net

Eine allgemeinere Überprüng ist mittels der von PHP erstellten Variable $_FILES['thefile']['type'] möglich. Dort speichert PHP den vom Browser übermittelten Mime-Type der Datei. Aber verlassen Sie sich nicht blind auf diese Angabe - da der Browser den Mime-Typ ermittelt, kann dieser sich auch irren - oder die Angabe wird sogar absichtlich manipuliert.

Eine Überprüfung, ob es sich bei dem hochgeladenen File um ein Word-Dokument handelt, könnte z.B. so aussehen:

Beispiel:

<?php
if(isset($_FILES['thefile']['tmp_name']) && $_FILES['thefile']['type']=="application/msword"){
// weiter mit der Verarbeitung }else{ if(isset($_FILES['thefile']['tmp_name'])){ die("Dieses File ist kein MS-Word Dokument sondern hat den Mime-Type ".$_FILES['thefile']['type']); }else{ die("Kein File übertragen") // man muss hier nicht zwingenderweise abbrechen, // das File kann auch freiwillig übermittelt worden sein, // je nach Anforderung } } ?>

Erläuterung:

Wir überprüfen damit, ob ein File übertragen wurde. Wird kein File übertragen, existiert $_FILES['thefile']['tmp_name'] nicht. Desweiteren überprüfen wir, ob das File den richtigen Filetyp hat.
Man könnte auch noch überprüfen, ob das File eine festgeschrieben Größe nicht überschreitet, aber in unserem Beispiel ist das nicht notwendig. (der Vollständigkeit halber:if($_FILES['thefile']['size']>1000000){})

Nachdem wir uns jetzt sicher sind, daß das File ein Word-Dokument ist und unseren Ansprüchen genügt, kopieren wir es an eine andere Stelle, um es auch nach dem Ende des Skriptes zur Verfügung zu haben.

Beispiel:

<?php
if(!move_uploaded_file($_FILES['thefile']['tmp_name'],"/pfad/zum/neuen/direktory/name.endung")){ // Ups, es passierte ein Fehler beim Kopieren } ?>

nach obennach unten

Weitere Informationen

Weitere Informationen zum Behandeln von File-Uploads mit PHP sind im PHP-Handbuch zu finden:

deutschsprachige Seite / englischsprachige Seite Abschnitt: Steuerung von Dateiuploads

Teil von SELFHTML aktuell Teil von Artikel Teil von PHP

© 2007 bereichsübergreifende Seite Impressum