5.9 KiB
Http Dateiuploads
In den Folgenden Beispielen wird gezeigt, wie man Http Datei Uploads realisieren und verarbeiten kann.
Einfacher Dateiupload
Frontend (HTML)
Der Dateiupload nutzt im Frontend ein HTML-Formular.
Wichtig: Parameter enctype="multipart/form-data
muss gesetzt sein.
<form action="?module=upload&action=upload" method="post" enctype="multipart/form-data">
<input name="file" type="file">
<input name="anotherfile" type="file">
<button type="submit">UPLOAD</button>
</form>
Verarbeitung in PHP
Bei einem Dateiupload werden die Dateien von PHP vor der Programmausführung entgegengenommen und in /tmp
gespeichert.
Zusätzlich werden die Informationen über den Upload in der $_FILES
Variable gespeichert.
var_dump($_FILES)
erzeugt diesen Output:
array (size=2)
'file' =>
array (size=5)
'name' => string 'my_uploaded_file.md' (length=19)
'type' => string 'text/markdown' (length=13)
'tmp_name' => string '/tmp/phphoXkRU' (length=14)
'error' => int 0
'size' => int 8972
'anotherfile' =>
array (size=5)
'name' => string 'my_other_file.txt.xml' (length=28)
'type' => string 'text/xml' (length=8)
'tmp_name' => string '/tmp/php2NqM0Z' (length=14)
'error' => int 0
'size' => int 9499
Verarbeitung im Controller
Auf die Uploadinfo kann man pro datei über die Request Klasse zugreifen:
$request = $this->app->Container->get('Request');
$fileUpload = $request->getFile('file');
getFile
liefert eine Instanz von FileUpload
zurück.
Validierung
Bevor der FileUpload weiterverwertet wird, sollte aus Sicherheitsgründen die Integrität des Uploads überprüft werden. Dafür stehen mehrere Methoden zur Verfügung:
$fileUpload->isValid()
prüft, ob die Datei zu einem gültigenPOST
Upload gehört und sollte immer ausgeführt werden.$fileUpload->isFile()
prüft, ob die Datei im/tmp
existiert.$fileUpload->isReadable()
prüft, ob die Datei gelesen werden kann.$fileUpload->hasError()
prüft, ob ein Http Error vorliegt.
Hinweis: Wenn ein Http Fehler vorliegt, kann man den Grund dafür per $fileUpload->getErrorMessage()
ermitteln
und ggf. an den Client weitergeben. Liegt allerdings kein Fehler vor, führt diese Methode zu einer Exception!
Speicherung
Wenn ein Upload dauerhaft gespeichert werden soll, muss die Datei aus dem /temp
an einen dauerhaften Speicherort
verschoben werden:
$fileUpload->move('/var/storage', 'upload.txt');
Hinweis: Wenn sich bereits eine Datei mit diesem Namen am Zielort befindet, wird eine Exception geworfen und die Datei wird nicht überschrieben oder anderweitig gespeichert.
Zugriff
Man kann auf zwei Arten auf den Inhalt des Uploads zugreifen:
$fileUpload->getContent()
liefert den Inhalt alsstring
zurück. (empfohlen für kleinere Dateien)$fileUpload->createContentStream()
liefert eineresource
, aus der der Inhalt gestreamed werden kann.
Tipp: Mit $fileUpload->getMimeType()
kann man vor dem Einlesen nocht prüfen, ob der User die Datei im
richtigen Format (json, csv, xml usw.) hochgeladen hat.
Dateiupload in Array
Frontend (HTML)
Für den Dateiupload können Dateien auch in zusammengehörigen Arrays hochgeladen werden.
Beispiel: Upload einer eigenen Schriftart. Hier werden vier dateien hochgeladen, die aber semantisch zusammengehören.
<form action="?module=upload&action=upload" method="post" enctype="multipart/form-data">
<input name="font[default]" type="file">
<input name="font[bold]" type="file">
<input name="font[italic]" type="file">
<input name="font[bolditalic]" type="file">
<button type="submit">UPLOAD</button>
</form>
Verarbeitung in PHP
In diesem Fall wird die $_FILES
Variable in einer anderen hierarchie aufgebaut:
array (size=1)
'font' =>
array (size=5)
'name' =>
array (size=4)
'regular' => string 'LiberationMono-Regular.ttf' (length=26)
'bold' => string 'LiberationMono-Bold.ttf' (length=23)
'italic' => string 'LiberationMono-Italic.ttf' (length=25)
'bolditalic' => string 'LiberationMono-BoldItalic.ttf' (length=29)
'type' =>
array (size=4)
'regular' => string 'font/ttf' (length=8)
'bold' => string 'font/ttf' (length=8)
'italic' => string 'font/ttf' (length=8)
'bolditalic' => string 'font/ttf' (length=8)
'tmp_name' =>
array (size=4)
'regular' => string '/tmp/phpN3NU7D' (length=14)
'bold' => string '/tmp/phpKzBu8u' (length=14)
'italic' => string '/tmp/php9wVd9l' (length=14)
'bolditalic' => string '/tmp/phpRYicad' (length=14)
'error' =>
array (size=4)
'regular' => int 0
'bold' => int 0
'italic' => int 0
'bolditalic' => int 0
'size' =>
array (size=4)
'regular' => int 108172
'bold' => int 105460
'italic' => int 124012
'bolditalic' => int 118296
Verarbeitung im Controller
Auf die Uploadinfo muss jetzt anders zugegriffen werden, da getFile
nur die oberste Ebene des Arrays ausgibt.
$request = $this->app->Container->get('Request');
$fileArray = $request->getFile('font');
$fontRegular = $fileArray['regular'];
$fontBold = $fileArray['bold'];
Alternativ ist auch möglich:
$request = $this->app->Container->get('Request');
$fileArray = $request->files->all();
$fontRegular = $fileArray['font']['regular'];
$fontBold = $fileArray['font']['bold'];
Beispiel: über alle Uploads iterieren:
$request = $this->app->Container->get('Request');
foreach($request->files as $fontType => $file) {
doSomething($fontType, $file);
}
Mit den einzelnen FileUpload
Objekten verfährt man nun genau wie im oberen Beispiel.
Hinweis: Die Hierarchie der Dateiuploads kann beliebig tief geschachtelt sein. Getestet wird aber nur bis zur dritten Ebene.