Datei Upload
Durch wenige, besondere Parameter im Formular und ein spezielles Feld, kann ich dem User ermöglichen seine Festplatte/Datenträger zu durchsuchen und Bilder oder Dateien auf meinen Server hochzuladen. Das input-Feld hat den type="file". Im globalen Array $_FILES sind die Informationen über das upload-File abgelegt.
Upload Dateiinformationen
$_FILES['fupload']
Die übermittelten Uploadinfos stecken im Array $_FILES['fupload']['name'], etc.
Falls eine Bilddatei hochgeladen wird (hier als Beispiel), werden das Bild und die Datei-Infos hier wiedergegeben. Die Indices im assoziativen Array Files - Feldname heissen: - name, size, tmp_name, type und error.
Das Upload Formular
Das Formular muss vom enctype="multipart/form-data" sein.
Die method="post" ist zwingend.
Das Formular ruft in der action seine Seite wieder auf, um den Upload zu vollziehen
und das Bild und die Dateiinformationen darzustellen.
In einem hidden-Field name="MAX_FILE_SIZE" unmittelbar vor dem
input type="file" wird die maximale Dateigrösse angegeben.
<form enctype="multipart/form-data" action="image_upload.php" method="post">
<p>
<input type="hidden" name="MAX_FILE_SIZE" value="102400" />
<input type="file" name="fupload" size="25" />
<label for="fupload">Max. 100 KB, nur gif, jpg oder png Bilder!</label>
</p>
<p>
<input type="submit" value="Hochladen" />
</p>
</form>
Mehrere Dateien gleichzeitig hochladen
Um den Upload mehrerer Dateien gleichzeitig zu ermöglichen, können mehrere input-Felder
vom type='file' in einem Formular aufeinander folgen. Wie bei Formularfeldern mit
Mehrfachauswahl muss der name='fupload[]' eine eckige Klammer haben,
damit ein Array entsteht. Die Uploadinfos sind dann entsprechend im als numerischer Array abrufbar:
$_FILES['fupload']['name'][0], etc.
MIME Type
Jede Datei hat einen Mime-Type mit dem sie sich z.B. als bestimmte Bild- oder
Programm-Datei identifiziert. Der Type wurde ursprünglich bei E-Mails dem Attachment mitgegeben,
MIME heisst Multipurpose Internet Mail Extension. Server und Browser kommunizieren miteinander,
so gibt der Server im Header an, was für eine Datei folgt, und der Browser kann diese akzeptieren oder ablehnen.
Den zweiteiligen mime-type (Medientyp/Subtyp) gebe ich auch bei Scripts an, z.B. text/CSS, text/html, text/javascript.
Auf diesen Type kann ich die hochzuladenede Datei prüfen mit
$_FILES['fupload']['type'] == "...", die gebräuchlichsten
MIME-Types für Uploads sind (in Klammern die Dateiendungen):
- EPS: application/eps (*.eps)
- PDF: application/pdf (*.pdf)
- Zip: application/zip (*.zip)
- mp2: audio/x-mpeg (*.mpg)
- MIDI: audio/x-midi (*.midi und *.mid)
- WAV: audio/x-wav (*.wav)
- GIF: image/gif (*.gif)
- ico: image/x-icon (*.ico)
- JPG: image/jpeg und image/jpg (*.jpeg und *.jpg)
- PNG: image/png (*.png)
- Tif: image/tiff und image/tif (.*tif und *.tiff)
Kontrollen
php.ini-Datei
Falls in der php.ini-Datei die Direktive 'file_uploads = On' nicht On ist, kann kein Upload getätigt werden.
Auch die Dateigrösse könnte dort eingeschränkt sein (z.B. auf 5 Megabite):
upload_max_filesize = 5M
und post_max_size = 5M.
- Am Anfang des Scripts wird geschaut, ob ein Uploadversuch unternommen wurde, wennn der Array $_FILES['fupload'] gesetzt ist, ist das der Fall.
- Als zweites wird auf Fehler überprüft und bei keinem Fehler das Script fortgesetzt. Die Fehlerursache könnte ausgegeben werden, sie liegt im Array $_FILES['fupload']['error']
- Im Verlaufe des Upload-Scripts werden die akzeptierten Endungen oder der MIME-Type der Datei bestimmt. Virendateien können vielerlei Endungen haben (php, inc, cgi, etc.), deshalb ist das Ausschlussverfahren nicht so zielführend wie das Einschränken.
- Der Speicherort (Ziel des Uploads) wird festgelegt und ein ev. vorhandener Pfad vor dem übermittelten Dateinamen gelöscht. Ich kann aber auch einfach hier der Datei einen andern Namen geben (umbenennen), um auf Nummer Sicher zu gehen.
-
Dann wird die Datei durch die Funktion
move_uploaded_file( $source, $target );endlich aus dem Temporären Ordner ans Ziel verschoben. Wenn eine gleichbenannte Datei bereits existiert, wir sie überschrieben. - Eine hochgeladene Datei (ausser ein Bild) sollte nicht ungeprüft ausgegeben werden, da sich dabei schädlicher Code verbreiten kann. Mann sollte die Datei zuerst zu sich herunterladen und dabei durch einen Virenscanner laufen lassen.
-
Auch sollten Dateien im Upload-Ordner nicht ausführbar sein. Im .htaccess dieses
Ordners muss stehen:
php_flag engine off
RemoveHandler .cgi
oder:
# Direkten Zugriff auf alle Dateien unterbinden
order deny,allow
deny from all
Das Upload Script
move_uploaded_file( $source, $target );
<?php
################################################################################
# Upload einer Bilddatei, nur gif, jpg oder png
################################################################################
// Versuch hat stattgefunden
if ( isset( $_FILES['fupload'] ) ) {
// Die Infos über die Datei im temporären Ordner werden am Browser ausgegeben.
// Da der Name vom User kommt, ist der zu entschärfen!
$name = $_FILES['fupload']['name'];
$name = basename($name); // ohne Pfad
$name = htmlspecialchars($name,ENT_QUOTES); // ohne Code
print "name: ". $name."<br />";
print "size: ". $_FILES['fupload']['size'] ." bytes<br />";
print "temp name: ".$_FILES['fupload']['tmp_name'] ."<br />";
print "type: ". $_FILES['fupload']['type'] ."<br />";
print "error: ". $_FILES['fupload']['error'] ."<br />";
// weiter wenn kein Fehler aufgetreten ist
if ($_FILES['fupload']['error'] == UPLOAD_ERR_OK) {
// bestimmen der hochladbaren Dateitypen
if ( $_FILES['fupload']['type'] == "image/gif" or "image/jpg" or "image/jpeg" or "image/png") {
if ($_FILES['fupload']['size'] < 102400) {
// suchen auf Server im Unix Standart Ordner namens /tmp
$source = $_FILES['fupload']['tmp_name'];
// senden an Ordner namens upload
$target = "upload/".$name;
move_uploaded_file( $source, $target );
// holen der Bildgroesse und Bild anzeigen
$size = getImageSize( $target );
$imgstr = "<p><img width=\"$size[0]\" height=\"$size[1]\" ";
$imgstr .= "src=\"$target\" alt=\"hochgeladenes Bild\" /></p>";
print $imgstr;
} else { echo "Die Datei ist zu gross! Maximal sind hier 100 KB erlaubt.";}
} else { echo "Es sind hier nur GIF, JPG oder PNG Bilder erlaubt.";}
print "Noch ein Upload?";
} else { echo "Ein Fehler ist aufgetreten.";}
} // ENDE
?>