• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Formular $_FILES zweiter aufruf vorbelegen

Cheffchen

Senior HTML'ler
[CLOSE] Hallo,

ich suche nach einer Möglichkeit in einem Formular den datei upload temporär zwischen zu speichern oder so.
Problem:
Ein Formular mit 3 Eingabefelder und 1 <input name="datei" type="file" />.
Wenn jetzt Datei Ausgewählt wurde und 2 Felder Ausgefühlt wurden und Senden geklickt wurde, wird die Seite neu aufgerufen mit Prüfungen der Eingaben. Jetzt wird ein Fehler festgestellt da 1 Feld nicht ausgefühlt ist und das Formular wird wieder angezeigt mit den schon vorhandenen Eingaben.
Aber was mach ich mit dem <input name="datei" type="file" /> da kann ich ja den Dateipfad nicht wieder vorbelegen?
Das $_FILES['datei']['tmp_name'] kann ich ja auch nicht zwischenspeichern da die temp Datei ja wohl nach erneuten Aufruf des Formular gelöscht wird.

Muss ich die Datei echt mit move_uploaded_file() erst irgendwo richtig zwischen speichern? das muss doch besser gehen.

Hoffe war verständlich :O)

Cheffchen
 
Zuletzt bearbeitet:
Bei normalen (Text-)Input Feldern kann man ja auf dem Server nach der Validierung das value-Attribut des Input-Feldes mit dem alten Wert belegen und damit vermeiden, dass die Eingabe nochmals gemacht werden muss. Aber das value-Attribut wird beim Input vom Typ file scheinbar nicht in dieser Weise unterstützt.

Ich sehe also auch nichts anderes als deine Idee, nämlich die akzeptierten Dateien zwischen zu lagern und nur die falsche neu anzufordern oder halt alle neu anfordern (was recht ärgerlich für den Benutzer ist). Aber es macht auch Sinn, denn der Fehler mit der 3. Datei kann ja zur Folge haben, dass er auch die anderen beiden noch ändern will.

Nachtrag: Hier ein Link mit Diskussion und Begründung http://forum.de.selfhtml.org/archiv/2002/6/t15741/
 
Zuletzt bearbeitet:
Musste das sein, genau das wollte ich nicht hören :O).
Ich habe gehoft das ich nur zu blöd bin.

Die Diskosion aus dem Link is mir klar und auch logisch, deswegen wollte ich ja nicht den Pfad zu der Datei zwischenspeichern sondern die temp Datei nach dem upload.

Aber trotzdem Danke

Cheffchen
 
Hallo Wustersoss,

tut mir echt leid aber mit der Antwort kann zumindest ich nichts Anfangen?

Was soll ich mit der Session_id machen?
Ich Arbeite ja mit Session, aber wie oben schon geschrieben bringt mir das ja nichts den temp_name zu speichern da die Datei selber wohl gelöscht wird bei einem neuen Senden des Formulars.

Idee:
ist es eigentlich möglich den Inhalt, also die Datei selber in eine session zu speichern?
So das ich nach her 2 variable habe, eine mit Dateinamen und eine für den inhalt der Datei?
Die Datei ist max 2MB groß also dürfte das doch kein problem sein.

Cheffchen
 
Du speicherst die Datei temporär in einem Ordner mit dem Namen der Session-ID und zeigst das Input-Feld für den Datei-Upload beim 2., mal nicht mehr an, da das ja nicht notwendig ist, wenn nur ein Feld nicht ausgefüllt ist. Wo ist da jetzt genau das Problem?
 
Ich würde folgendes Vorschlagen (habe ich selbst schonmal so genutzt):
Speichere alle Inhalte von $_FILES in einer Session-Variable, z.B. $_SESSION["files"], auch temp_name etc. Zusätzlich holst Du dir den Binärcode der hochgeladenen Datei in eine Variable und speicherst diese ebenfalls in der Session:
PHP:
$_SESSION["files][$x] = file_get_contents($_FILES["temp_name"][$x]);

Dadurch brauchst Du keine Dateien lokal zwischenspeichern, hast alles in der Session.

Nachteil: wenn der Blob sehr groß ist, sprengt es ggfs. die Session-Grenzen. Daher ist es immer gut auch eine Upload-Großenbegrenzung einzustellen.
 
Alle vorgeschlagenen Lösungen, einen zweiten Upload zu verhindern gehen nicht, wenn mein Einwand ganz am Anfang zum Tragen kommt:

Aber es macht auch Sinn, denn der Fehler mit der 3. Datei kann ja zur Folge haben, dass er auch die anderen beiden noch ändern will.

Außerdem musst bei der Lösung einen Aufräumjob haben, denn wenn der Benutzer nach 2 Dateien die Nase voll hat und die 3. nicht mehr hoch lädt, sondern einfach den Browser zumacht und nach Hause geht, dann musst deine beiden anderen wieder entsorgen :-)
 
Hallo NetAktiv,

hatte jetzt für einen Moment gedacht, ich hätte falsch verstanden, was ich am Anfang gelesen hatte, aber dem ist nicht so, denke ich. Cheffchen möge ggf. aufklären.

Sie oder Er schrieb
Ein Formular mit 3 Eingabefelder und 1 <input name="datei" type="file" />.

Habe es jetzt so verstanden, dass 3 INPUT-Text-Felder sind plus einem Feld für eine Datei, welche hochgeladen werden kann.

Außerdem musst bei der Lösung einen Aufräumjob haben, denn wenn der Benutzer nach 2 Dateien die Nase voll hat und die 3. nicht mehr hoch lädt, sondern einfach den Browser zumacht und nach Hause geht, dann musst deine beiden anderen wieder entsorgen
lAAAAAAAAACH5BAEAAA4ALAAAAAAPAA8AAARb0EkZap3YVabOGRcWcAgCnIMRTEEnCCfwpqt2mHEOagoOnz+CKnADxoKFyiHHBBCSAdOiCVg8KwPZa7sVrgJZQWI8FhB2msGgwTXTWGqCXP4WBQr4wjDDstQmEQA7
Da haste natürlich recht. Ist schon bei einer Datei so.
 
Ich denke, ich hab da anfangs zu viel rein interpretiert, gibt wohl echt nur ein file-Feld, aber das ändert nichts an den prinzipiellen Problematiken, wenn die Eingabe unvollständig ist. Man kann natürlich erst mal die netten JavaScript aktiven Benutzer lokal kontrollieren, aber ...

Da haste natürlich recht. Ist schon bei einer Datei so.
War mir schon klar, aber ich dachte 2 klingt dramatischer als 1 :-)
 
Hallo,

genau das mit dem realen zwischenspeichern wollte ich nicht machen, wenn es zu umgehen geht.
PHP 5.4 steht nicht zur verfügung
Zur Aufklärung (dachte ihr seit schon älter und hättet das hinter euch):O)
Ja, 3 text input und 1 file input, wo halt nach senden PHP prüfungen sind und bei einem Fehler das Formular neu angezeigt wird mit allen schon richtigen eingaben, ausser halt file das geht immer verloren.

Das von threadi
$_SESSION["files"][$x] = file_get_contents($_FILES["temp_name"][$x]);
hört sich erstmal schick an ob wohl mir noch nicht klar ist wie ich das wieder zussammen setzte, das PHPMailer wieder eine Datei bzw Anhang draus macht.

Cheffchen
 
Der gesamte File-Content wird ja dann im $_Session-Array gespeichert und somit hast den Inhalt beim zweiten POST ja schon, falls du kein File-Input Feld auf die Oberfläche bringst. Dann musst halt prüfen, ob die Form mit oder ohne $_FILES gepostet wurde und wenn ohne, dann die Daten aus dem Session-Array. Ich finde diese Lösung nach wie vor nicht gut, weil alle Angaben eines Formulars aus meiner Sicht zusammen gehören. Wenn also ein Text-Wert falsch ist, die Datei aber richtig, dann wird die Datei nicht mehr zum Upload angeboten. Das kann aber aus Sicht des Benutzers unerwünscht sein, denn mit dem korrigierten Text kann ja auch die zunächst gewählte Datei veraltet sein. Könntest halt eine Checkbox machen mit [x] alte Datei OK und zusätzlich ein (leeres) File-Upload. Dann kann der Benutzer wählen, wenn er versteht, was du meinst :-).
 
Hallo NetAktiv,

deine einwand habe ich verstanden, meiner Erfahrung ist aber das dies genau eine sehr große fehler-/nervquelle ist da wenn bei einem Formular alle Daten erhalten bleiben die richtig sind, geht der user davon aus das wenn die Datei richtig ist auch erhalten bleibt.

Habe mit 30 Usern das getestet mit verschärfter Prüfung das mindest einmal eine Fehlermeldung kommt, genau 27 haben nach korrigieren des Fehlers die Datei nicht mehr ausgewählt mit der Begründung, kam doch keine Fehler anzeige bei Datei.
Ich muss zugeben ich währe auch einer der 27 gewesen.

Deswegen versuche ich das mit der Session
Mit einer Option neuer Upload, hast recht.
(bekommen das leider bis jetzt noch nicht wieder zusammen gesetzt :O( )

Cheffchen
 
Mit einer Option neuer Upload, hast recht.
(bekommen das leider bis jetzt noch nicht wieder zusammen gesetzt :O( )

Ich würde halt bei einem Fehler, bei dem die Datei aber schon OK war und auf dem Server ist, dann zwei Objekte anzeigen
1) Eine Checkbox mit dem Text: Zuletzt verwendete Datei verwenden
2) Einen File-Input mit dem Text: Datei neu auswählen.
Der Benutzer muss dann entweder die Checkbox aktivieren oder eine Datei neu auswählen. Prinzipiell könntest das auf dem Client noch dynamisch sichtbar machen, also den File-Input nur, wenn die Checkbox nicht aktiviert ist.
Man könnte die Checkbox auch als Default aktiviert haben, aber recht sicher nehmen 99% ohne Nachdenken die Voreinstellung :-).
Auf jedem Fall kannst auf dem Server dann prüfen, ob eins der beiden aktiv ist, und entweder nimmst halt die alte oder die aktuelle Datei.
 
Das von threadi hört sich erstmal schick an ob wohl mir noch nicht klar ist wie ich das wieder zussammen setzte, das PHPMailer wieder eine Datei bzw Anhang draus macht.

Ich nutze PHPMailer nicht, aber im Prinzip läuft es nur auf folgendes hinaus:
Du hast einen Blob in der Session-Variable.
Du brauchst einen base64-kodierten String in einer Variable die Du zum Mail senden brauchst.
Also:

PHP:
$base64kodiert = base64_encode($_SESSION["files][$x]);
 
Hallo threadi und andere Helfer, Danke,

also das hat jetzt geklappt mit der upload datei in eine session zu speichern falls eine andere Prüfung das versenden stopt.
Ich habe das jetzt so gelöst das wenn Datei OK war das Farblich und mit text kentlich gemacht wird das die Datei schon im Speicher ist.

Hier mal ein zusammenfassung (danke threadi, das base64 habe ich nicht gebraucht war nur ein anderer befehle zum einfügen)
Das Formular ist ja klar mit <input name="datei" type="file" />
die Verarbeitung nach dem Senden (gleiches Formular)
PHP:
  if($_FILES['datei']['tmp_name']){
  $size=getimagesize($_FILES['datei']['tmp_name']);
  if( $size[2] != 1 && $size[2] != 2 && $size[2] != 3){$fehler['datei']=1;$FEHLER.="Bitte nur gif, jpg oder png<br>";}
    #Typ der Grafik 1 = GIF, 2 = JPG, 3 = PNG ...
  if($_FILES['datei']['size'] > '2097152'){$fehler['datei']=1;$FEHLER.="Datei darf max. 2MB sein<br>";} 
  $_SESSION['files']['datei_name']=$_FILES['datei']['name'];                                # das ist Datei Name Speichern in session
  $_SESSION['files']['contents'] = file_get_contents($_FILES['datei']['tmp_name']); # das ist Datei Speichern in session
 }

in PHPMAILER währe es dann so (DA CMS, mit mail() funktion ähnlich)
PHP:
  if($_SESSION['files']['datei_temp']){
       $mail->AddStringAttachment($_SESSION['files']['contents'],$_SESSION['files']['datei_name']);
  }

Cheffchen
 
Da ja auch ich gelernt habe, dass es nur eine Datei gibt, würde ich auch zum Speichern in der Session kein Array nehmen, sondern statt

Code:
[LEFT][COLOR=#0000BB][FONT=monospace]$_SESSION[/FONT][/COLOR][COLOR=#007700][FONT=monospace][[/FONT][/COLOR][COLOR=#DD0000][FONT=monospace]'files'[/FONT][/COLOR][COLOR=#007700][FONT=monospace]][[/FONT][/COLOR][COLOR=#DD0000][FONT=monospace]'datei_name'[/FONT][/COLOR][COLOR=#007700][FONT=monospace]]=[/FONT][/COLOR][COLOR=#0000BB][FONT=monospace]$_FILES[/FONT][/COLOR][COLOR=#007700][FONT=monospace][[/FONT][/COLOR][COLOR=#DD0000][FONT=monospace]'datei'[/FONT][/COLOR][COLOR=#007700][FONT=monospace]][[/FONT][/COLOR][COLOR=#DD0000][FONT=monospace]'name'[/FONT][/COLOR][COLOR=#007700][FONT=monospace]]; [/FONT][/COLOR][FONT=monospace][COLOR=#ff8000]# das ist Datei Name Speichern in session[/COLOR][/FONT]
[COLOR=#0000BB][FONT=monospace]$_SESSION[/FONT][/COLOR][COLOR=#007700][FONT=monospace][[/FONT][/COLOR][COLOR=#DD0000][FONT=monospace]'files'[/FONT][/COLOR][COLOR=#007700][FONT=monospace]][[/FONT][/COLOR][COLOR=#DD0000][FONT=monospace]'contents'[/FONT][/COLOR][COLOR=#007700][FONT=monospace]] = [/FONT][/COLOR][COLOR=#0000BB][FONT=monospace]file_get_contents[/FONT][/COLOR][COLOR=#007700][FONT=monospace]([/FONT][/COLOR][COLOR=#0000BB][FONT=monospace]$_FILES[/FONT][/COLOR][COLOR=#007700][FONT=monospace][[/FONT][/COLOR][COLOR=#DD0000][FONT=monospace]'datei'[/FONT][/COLOR][COLOR=#007700][FONT=monospace]][[/FONT][/COLOR][COLOR=#DD0000][FONT=monospace]'tmp_name'[/FONT][/COLOR][COLOR=#007700][FONT=monospace]]); [/FONT][/COLOR][COLOR=#FF8000][FONT=monospace]# das ist Datei Speichern in session[/FONT][/COLOR][/LEFT]

einfach

Code:
[LEFT][COLOR=#0000BB][FONT=monospace]$_SESSION[/FONT][/COLOR][COLOR=#007700][FONT=monospace][[/FONT][/COLOR][COLOR=#DD0000][FONT=monospace]'file_[/FONT][/COLOR][COLOR=#DD0000][FONT=monospace]name'[/FONT][/COLOR][COLOR=#007700][FONT=monospace]] = [/FONT][/COLOR][COLOR=#0000BB][FONT=monospace]$_FILES[/FONT][/COLOR][COLOR=#007700][FONT=monospace][[/FONT][/COLOR][COLOR=#DD0000][FONT=monospace]'datei'[/FONT][/COLOR][COLOR=#007700][FONT=monospace]][[/FONT][/COLOR][COLOR=#DD0000][FONT=monospace]'name'[/FONT][/COLOR][COLOR=#007700][FONT=monospace]]; [/FONT][/COLOR][COLOR=#FF8000][FONT=monospace]# das ist Datei Name Speichern in session
[/FONT][/COLOR][COLOR=#0000BB][FONT=monospace]$_SESSION[/FONT][/COLOR][COLOR=#007700][FONT=monospace][[/FONT][/COLOR][COLOR=#DD0000][FONT=monospace]'file_[/FONT][/COLOR][COLOR=#DD0000][FONT=monospace]contents'[/FONT][/COLOR][COLOR=#007700][FONT=monospace]] = [/FONT][/COLOR][COLOR=#0000BB][FONT=monospace]file_get_contents[/FONT][/COLOR][COLOR=#007700][FONT=monospace]([/FONT][/COLOR][COLOR=#0000BB][FONT=monospace]$_FILES[/FONT][/COLOR][COLOR=#007700][FONT=monospace][[/FONT][/COLOR][COLOR=#DD0000][FONT=monospace]'datei'[/FONT][/COLOR][COLOR=#007700][FONT=monospace]][[/FONT][/COLOR][COLOR=#DD0000][FONT=monospace]'tmp_name'[/FONT][/COLOR][COLOR=#007700][FONT=monospace]]); [/FONT][/COLOR][COLOR=#FF8000][FONT=monospace]# das ist Datei Speichern in session[/FONT][/COLOR][/LEFT]

aber das ist mehr Kosmetik.
 
Zurück
Oben