PHP – Dateiupload mit Überprüfung

PHP - Dateiupload mit ÜberprüfungBei der Programmierung von Skripten kommt man vielleicht in die
Notwendigkeit, den User Dateien auf den Server übertragen zu
lassen. Mit PHP ist dies fast ein Kinderspiel…

Mit PHP lassen sich viele kleine nützliche Skripte entwickeln.
So auch ein PHP Skript, mit welchem man Benutzer Dateien auf den
Server übertragen lassen kann.
Aus HTML-Sicht sieht ein File-Upload etwa so wie im folgenden Beispiel
aus.

<form enctype="multipart/form-data" action="<?php
echo $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>

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 $PHP_SELF; ?>"
Die PHP-Variable $PHP_SELF enthält den Namen (+ evtl. Pfad)
des aktuellen Dokumentes. Selbstverständlich kann auch ein
eigener Name angegeben werden

<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.

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:

<html>
<!-- Der Kopf der HTML seite inkl evt. layout //-->
<?php
if(isset($submit) && $submit=="Senden"){
// Das Formular wurde gesendet
}else{
// Das Formular wird angezeigt werden
?>
<!-- Das Formular //-->
<?php } ?>

Der Fall "Das Formular wurde gesendet" tritt ein, wenn
der User den Submit-Button gedrückt hat. Darauf können
wir mit der angegebenen Datei arbeiteten.
Hierfür stellt uns PHP freundlicherweise einige Variablen zur
Verfügung.

Die Namen dieser Variablen setzen sich aus dem Namen des Formularfeldes
(in unserem fall $thefile) und einem Suffix zusammen.

$thefile
Pfad und Name der Datei wie sie im Filesystem zu finden ist.

(meistens in der Form /tmp/php234lksdaflk)

$thefile_name
Der Name der Datei, wie sie auf dem Clientsystem genannt wurde


$thefile_size

Die Größe der Datei in Bytes

$thefile_type
Der Mime-Type der Datei, sofern der Browser diese Information mitlieferte.
(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.
Dabei richtet sich die Dateiüberprüfung sehr auf den erwarteten
Dateityp.

Wenn es sich um Bilder in den Format *.jpg oder *.gif handelt, die
Funktion getimagesize() verwendet werden. Diese gibt ein
Array mit Informationen über das Bild zurück.

$size=getimagesize($thefile);
$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=[…]".

Eine allgemeinere Überprüng ist mittels der von PHP erstellten
Variable $thefile_type möglich.
Diese enthält den jeweiligen Mime-Type der Datei.
Eine Überprüfung, ob es sich bei dem hochgeladenen File
um ein Word-Dokument handelt, könnte z.B. so aussehen:

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

Hiermit wird überprüft, ob ein File übertragen wurde.
Wird kein File übertragen, enthält $thefile den
Wert ‘none’. Desweiteren wird überprüft, ob das File den
richtigen Filetyp hat.
Zudem kann auch das Einhalten der maximalen Dateigröße
überprüft werden.

<?php
if($thefile!="none" && $thefile_type=="application/msword"){
if($thefile_size<1000000){
// weiter mit der Verarbeitung
} else {
echo "Das Word-Dokument ist zu groß!";
}
}else{
if($thefile!="none"){
die("Dieses File ist kein MS-Word Dokument sondern hat den
Mime-Type ".$thefile_type);
}else{
die("Kein File übertragen")
// man muss hier nicht zwingenderweise abbrechen,
// das File kann auch freiwillig übermittelt worden sein,
// je nach Anforderung
}
}
?>

Ist das Word-Dokument größer als $thefile_size<1000000,
dann wird die Fehlermeldung ausgegeben.

Nachdem wir uns jetzt sicher sind, daß das File ein Word-Dokument
ist, welches nicht größer als 1000000 Bytes ist, können
wir es an eine andere Stelle auf den Server kopieren.

<?php
if($thefile!="none" && $thefile_type=="application/msword"){
if($thefile_size<1000000){
if(!copy ($thefile,"/pfad/zum/neuen/direktory/name.endung")){
// Ups, es passierte ein Fehler beim Kopieren
} else {
echo "Das File wurde erfolgreich auf den Server übertragen!";
}
} else {
echo "Das Word-Dokument ist zu groß!";
}
}else{
if($thefile!="none"){
die("Dieses File ist kein MS-Word Dokument sondern hat den
Mime-Type ".$thefile_type);
}else{
die("Kein File übertragen")
// man muss hier nicht zwingenderweise abbrechen,
// das File kann auch freiwillig übermittelt worden sein,
// je nach Anforderung
}
}
?>

Das Kopieren wird vom hinzugefügten copy() Befehl
ausgeführt. Hinter der Quelle, die in $thefile angegeben ist,
steht das Ziel wohin das File kopiert werden soll.
Und das wars auch schon.

This entry was posted in PHP. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *