Thomas L.: formmailer mit attachment und sessions

Hallo,

ich versuche schon ewig, einen Formmailer mit Attachment zu erstellen. Klappt auch alles wunderbar, nur da nach dem ersten Absenden die Datei verloren geht, wollte ich diese kopieren und in einer session sichern. Dann möchte ich das Formular so lange vorsetzen, bis alle Felder ausgefüllt sind. Leider funzt es nicht. Ich kann den Fehler einfach nicht finden. Was mache ich falsch?
Die Datei sichere in der Variable $_SESSION['file'], diese geht aber nach einem erneuten Absenden verloren. Außerdem erhalte ich dann auch noch die Meldung "Die Übertragung der Datei ist fehlgeschlagen. Bitte versuchen Sie es erneut.", die eigentlich nur dann erscheinen soll, wenn eine Datei hochgeladen wurde (isset($_FILES) und der Upload nicht geglappt hat.

(der untenstehende Script ist nur auszugsweise)

Vielen Dank schon mal im voraus.

Thomas L.

<?php
session_start();

if ($_POST[sent]==1) {
  $max_attach_size = 2097152;

//Überprüfung ob alle Felder ausgefüllt sind

//Datei hochladen und kopieren
  if (isset($_FILES['file'])) {
      if ($_FILES['file']['size'] > $max_attach_size) {
        $errors[] = "<strong>Attachment zu groß (".number_format($_FILES['file']['size']/1048576,2,",","")." MB) - Maximalgröße: ".number_format($max_attach_size/1048576,0,",","")." MB</strong>";
        }
      elseif ($_FILES['file']['error'] != UPLOAD_ERR_OK) {
        $errors[] = "Die Übertragung der Datei ist fehlgeschlagen. Bitte versuchen Sie es erneut.";
        }
      else {
        $file_copy = "tmp/".$_FILES['file']['name'];
        move_uploaded_file($_FILES['file']['tmp_name'],$file_copy);
        $_SESSION['file'] = $file_copy;
        }
      }

//Wenn alle Pflicht-Felder ausgefüllt, Mail aufbauen und versenden
  if (empty($errors)) {
      $boundary = md5(rand());
      $header = "From: $email_from";
      $header .= "\r\nReply-To: $email";
      $header = "\r\nX-Mailer: PHP/" . phpversion();
      $header .= "\r\nX-Sender-IP: $REMOTE_ADDR";
      $header .= "\r\nReturn-Path: <$email>";
      $header .= "\nMIME-Version: 1.0";
      $header .= "\nContent-Type: multipart/mixed; boundary=$boundary";
      $header .= "\n\nThis is a multi-part message in MIME format  --  Dies ist eine mehrteilige Nachricht im MIME-Format";
      $header .= "\n\n--$boundary";
      $header .= "\nContent-Type: multipart/alternative; boundary=$boundary";
      //Mail-Text
      $header .= "\n\n--$boundary";
      $header .= "\nContent-Type: text/plain";
      $header .= "\nContent-Transfer-Encoding: 8bit";
      $header .= "\n\n".$textf;
      //Mail-HTML
      $header .= "\n\n--$boundary";
      $header .= "\nContent-Type: text/html";
      $header .= "\nContent-Transfer-Encoding: 8bit";
      $header .= "\nContent-Description: HTML";
      $header .= "\n\n";
      $header .= "\n".$message;
      $header .= "\n\n--$boundary--";
      //Attachment
      if (isset($_SESSION['file'])) {
        $datei_content = fread(fopen($_SESSION['file'],"r"),filesize($_SESSION['file']));
        $datei_content = chunk_split(base64_encode($datei_content),76,"\n");
        $header .= "\n\n--$boundary";
        $header .= "\nContent-Type: ".$_FILES['file']['type']."; name="".$_FILES['file']['name'].""";
        $header .= "\nContent-Transfer-Encoding: base64";
        $header .= "\nContent-Disposition: attachment; filename="".$_FILES['file']['name'].""";
        $header .= "\n\n".$datei_content;
        }
      $header .= "\n\n--$boundary--";
      // Sende E-Mail und gebe Fehler bzw. Bestaetigung aus
      if (mail($email_to,$betreff,"",$header)) { $mail_send = true; }
      else { $errors[] = "Die Informationsübermittlung ist fehlgeschlagen, bitte versuchen Sie es später noch einmal.<br>"; }

// Ausgabe der Antwortseite:
      if (isset($mail_send)) {
        echo "<h1>Vielen Dank für Ihre Anfrage</h1>"
        if (isset($_SESSION['file'])) {
            unlink($_SESSION['file']);
            session_unset();
            session_destroy();
            }
        }//schließende Klammer für (isset($mail_send))
      }//schließende Klammer für empty($errors)

  1. hi,

    Die Datei sichere in der Variable $_SESSION['file'], diese geht aber nach einem erneuten Absenden verloren.

    was meinst du damit?

    $file_copy = "tmp/".$_FILES['file']['name'];
            move_uploaded_file($_FILES['file']['tmp_name'],$file_copy);
            $_SESSION['file'] = $file_copy;

    hier schreibst du lediglich den dateinamen in die session.

    was gibt den eine überprüfung des session-inhaltes direkt nach dem starten der session auf der betroffenen seite, bspw. über print_r($_SESSION)?

    gruß,
    wahsaga

    --
    "Look, that's why there's rules, understand? So that you _think_ before you break 'em."
    1. Hallo,

      $file_copy = "tmp/".$_FILES['file']['name'];
              move_uploaded_file($_FILES['file']['tmp_name'],$file_copy);
              $_SESSION['file'] = $file_copy;

      was gibt den eine überprüfung des session-inhaltes direkt nach dem starten der session auf der betroffenen seite, bspw. über print_r($_SESSION)?

      nach dem ersten Absenden enthält die SESSION-Variable file = tmp/datei.xyz und nach dem erneuten Absenden nur noch "file = tmp/"

      Was mache ich falsch?

      Thomas L.

      1. hi,

        nach dem ersten Absenden enthält die SESSION-Variable file = tmp/datei.xyz und nach dem erneuten Absenden nur noch "file = tmp/"

        Was mache ich falsch?

        vermutlich überschreibst du ihren wert irgendwo wieder.

        gruß,
        wahsaga

        --
        "Look, that's why there's rules, understand? So that you _think_ before you break 'em."
        1. Hallo,

          nach dem ersten Absenden enthält die SESSION-Variable file = tmp/datei.xyz und nach dem erneuten Absenden nur noch "file = tmp/"

          vermutlich überschreibst du ihren wert irgendwo wieder.

          Danke für den Hinweis. Aber leider wüsste ich nicht wo.
          Da sich das Formular selbst wieder aufruft, kann es vielleicht daran liegen? Aber beim erneuten Absenden bleibt doch das

          Attachment: <input type="file" name="file">

          leer. So dass doch auch die Variable $_FILES nicht gesetzt werden dürfte, oder?

          Gruß
          Thomas L.

          1. hi,

            Da sich das Formular selbst wieder aufruft, kann es vielleicht daran liegen?

            ja, das würde ich vermuten.

            Aber beim erneuten Absenden bleibt doch das
            Attachment: <input type="file" name="file">
            leer. So dass doch auch die Variable $_FILES nicht gesetzt werden dürfte, oder?

            denke ich nicht.
            es wurde zwar keine datei ausgewählt, aber trotzdem ein fileupload-formular abgesendet.

            in solchen situationen empfiehlt es sich, nicht zu "vermuten", wie PHP wohl reagieren könnte, sondern es explizit zu verifizieren.
            print_r($_FILES) beispielsweise sollte über struktur und inhalt dieses arrays ausreichende auskünfte gegen können.

            gruß,
            wahsaga

            --
            "Look, that's why there's rules, understand? So that you _think_ before you break 'em."
            1. Hallo,

              danke nochmal für deine Hinweise.

              es wurde zwar keine datei ausgewählt, aber trotzdem ein fileupload-formular abgesendet.

              wie könnte ich denn dann umgehen, dass die SESSION-Variable wieder überschrieben wird?

              Thomas L.

              1. hi,

                wie könnte ich denn dann umgehen, dass die SESSION-Variable wieder überschrieben wird?

                in dem du abprüfst, ob ein erneuter upload einer datei stattgefunden hat, oder nicht.
                dazu solltest du mal vergleichen, was $_FILES in den beiden fällen enthält, und welches kritierium hier als unterscheidung dienen könnte (dateigröße beispielsweise).

                oder du umgehst das problem, in dem du die session-var nur dann befüllst, wenn sie noch keinen inhalt hat bzw. noch nicht gesetzt ist. das wird dann aber problematisch, wenn der user doch mal noch eine neue datei hochladen sollte ...

                gruß,
                wahsaga

                --
                "Look, that's why there's rules, understand? So that you _think_ before you break 'em."