Kontaktformular

ist in der Seite eingebaut, in der das Kontaktformular ist; verweist auf sich selbst, verarbeitet dort auch die übergebenen Daten und gibt Fehlermeldungen aus. Das Formular wird wiederholt, und die fehlerhaften Daten voreingetragen
##### Ziel-email-Adresse, unbedingt ändern ######
$mailto = "irgendwer@irgendwas.de"; // ÄNDERN


##### Allgemeine Variablen vorbereiten
$formactionziel= $_SERVER["PHPSELF"];
$zeit=strftime("%c", time());
$mail_text="Anfrage vom $zeit \n \n";
$betreff= "Anfrage";
$from="From: Kontaktformular@".$_SERVER['SERVER_NAME'];
$meldung="";


######### Die HTML-Ausgabe beginnt
// es beginnt der gesamte HTML-Abschnitt, in welchem Formular und oder Meldungen erscheinen
echo "<div style='margin-left:2cm; font-family:Arial; font-size:10pt'>";

########## Abschnitt 1 ##########
// folgt ein Abschnitt, der nur greift, wenn bereits Daten übersandt wurden; die Daten werden verarbeitet, um sie entweder zur Speicherung oder, bei Fehlern im erneut aufzurufenden Formular voreinzutragen.

if (isset($_POST["submit"])) {

// übergebene Variablen ermitteln:
$felder="absendername strasse plz ort tel absenderemail anmerkung";
$felder=explode(" ", $felder);
unset($errors);
foreach($felder as $tmp) {

if(trim(stripslashes($_POST[$tmp]))=="asdf") $errors[]="$tmp = asdf? Was soll das!?";
// kleines Gimmick für den Fall, dass jemand rumspielt und asdf eingibt

$$tmp=trim(stripslashes($_POST[$tmp]));
}


// Sicherheits-Überprüfung der Daten aus Übervorsicht,
// eigentlich nicht nötig, sofern $mailto oben fest definiert ist

if ($mailto != "" and !preg_match("/^[^@]+@.+\.\D{2,5}$/", $mailto)) {
$errors[] = "die E-Mail-Adresse sieht nicht richtig aus<br />";
$absenderemail="!!??!!";
}

// Pflichtfelder checken ----------------------------------------------------------- evtl. ÄNDERN -----------------
// soweit eine der folgenden Felder KEIN Pflichtfeld ist, muss man
// die entsprechende Zeile löschen oder auskommentieren

if(empty($ort)) $errors[]="Ort fehlt<br />";
if(empty($plz)) $errors[]="Postleitzahl fehlt<br />";
if(empty($strasse)) $errors[]="Straße fehlt<br />";
if(empty($tel)) $errors[]="Telefonnummer fehlt<br />";
if(trim($anmerkung)=="asdf") $errors[]="Hast Du nichts Besseres zu tun?";


// Wenn keine Fehler da sind, kann die Post abgehen.
if (empty($errors)) {
$mail_text="
Anfrage
-------
Name: $absendername
Strasse: $strasse
Ort: $plz $ort
Telefon: $tel
Email: $absenderemail
Nachricht:
$anmerkung ";
// keine HTML-Zeilenumbrüche; die hier notierten Zeilenumbrüche erscheinen 1:1 im email-Text

// Refererdaten vorbereiten, um sie der email-Nachricht hinzufügen zu können
$referer=$_SERVER["HTTP_REFERER"];
$IP=$_SERVER['REMOTE_ADDR'];
$remotehost=$_SERVER['REMOTE_HOST'];

$refererdaten="
http_referer: $referer
IP=$IP
remote_host=$remotehost
";

// referer-Daten an den email-Text anhängen

$mail_text.="
--------------
Protokollierung interner Daten für Kontrollzwecke:
$refererdaten
";

// mail versenden
if (@mail($mailto, $betreff, $mail_text, $from)) {
$sent = true;
}else {
$errors[] = "keine Verbindung zum Mailserver - bitte nochmal versuchen<br />";
}

}
}

// Bestätigungsanzeige für den User

if($sent===true) {
echo "<p style='color:green; font-size:13pt'><b>Danke!</b><br />Nachricht erfolgreich versandt.</p>";

// hier könnte man auch abbrechen und link zurück auf die eigene Seite mit dem blanken Formula setzen,
// anderenfalls muss man zunächst die Formularinhalte wie folgt löschen
foreach($felder as $tmp) {
$$tmp="";
}
// Ende des Löschens der Formularinhalte
}

echo "Neue Nachricht: <br /><hr><br />";

###### Ende Abschnitt 1 ############

###### Abschnitt 2 #############
// Dieser Abschnitt schließt am Abschnitt 1 an, und greift nur, wenn dort ein Fehler bemerkt wurde
// sie bereitet im Falle einer Fehlermeldung die Fehlerhinweise vor
// und bereitet die übersandten Daten auf, um sie im Formula voreinzutragen

if (empty($sent)) {
if(isset($errors)) {
echo "<p>Hoppla. Fehler aufgetreten:</p><ul>";
foreach($errors as $f) {
echo "<li>".$f."</li>";
}
echo "</ul><br /><br />";

$action=$_SERVER["PHP_SELF"];

// folgendes wird in ähnlichen Skripten gern übersehen; wenn in Eingabefeldern ein Apostroph war, wurde das beim Übersenden mit slashes maskiert, und diese Slashes würden im Eingabefeld erscheinen. Diese müssen entfernt werden. Beim erfolgreichen Speichern in eine Datenbank dagegen übernimmt das php-Programm die Entfernung automatisch, so dass obige Routine nur notwendig ist, wenn die Variablen auf der Webseite wiedergegeben werden müssen

$absendername=htmlentities(stripslashes($absendername));
$absenderemail=htmlentities(stripslashes($absenderemail));
$strasse=htmlentities(stripslashes($strasse));
$anmerkung= htmlentities(stripslashes($anmerkung));
$ort=htmlentities(stripslashes($ort));


} // ende errors
}
####### Ende Abschnitt 2 ########

####### Abschnitt 3 #############
// ab hier der normale Content dieser Seite, der beim Erstaufruf erscheint, der Content besteht
// aus dem Formular, evtl. mit voreingetragenen Daten im Falle einer misslungenen Absendung
echo "
<form action='$formactionziel' method='post'>
<INPUT TYPE='TEXT' NAME='absendername' value='$absendername' SIZE='42'> Name, Vorname<br />
<INPUT TYPE='TEXT' NAME='strasse' value='$strasse' SIZE='42'> Straße und Hausnr.<br />
<INPUT TYPE='TEXT' NAME='plz' value='$plz' SIZE='6'> PLZ<br />
<INPUT TYPE='TEXT' NAME='ort' value='$ort' SIZE='42'> Ort<br />
<INPUT TYPE='TEXT' NAME='tel' value='$tel' SIZE='42'> Telefon<br />
<INPUT TYPE='TEXT' NAME='absenderemail' value='$absenderemail' SIZE='40'> E-Mail (optional)<br /><br />
Nachricht:<br />
<textarea name='anmerkung' cols='40' rows='10'>$anmerkung</textarea><br />
<br />
<INPUT TYPE='SUBMIT' name='submit' VALUE='Absenden'>
</form>
<br />
</div>";

email mit Anhang versenden

Im php-Handbuch (http://www.php.net/manual/de/function.mail.php) gibt es kein Anwendungsbeispiel und nur wenig hilfreiche Verweise. Zitat:

Hinweis: E-Mails mit Anhängen und speziellen Inhalten (wie HTML) können mit dieser Funktion versendet werden. Dazu wird MIME-Encoding verwendet. Weitere Informationen dazu finden Sie in einem » Zend-Artikel und in den » PEAR-Mime-Klassen.
 

Der zititerte Aufsatz auf zend.com (in englisch) ist nicht wirklich hilfreich.

Auch in der php-FAQ findet man kein Beispiel. Zitat:

Wie kann ich ein Attachment mit einer Mail versenden?
http://php-faq.de/q-mail-attachment.html

Bei der mail()-Funktion von PHP kann man im vierten Argument jeden beliebigen zusätzlichen Header angeben. Attachments werden MIME-kodiert. Eine HTML Mime Mail class kapselt diese Funktionalität und macht die ganze Geschichte recht einfach. Unter der genannten URL finden sich auch Anwendungsbeispiele.

Die korrekte Programmierung ist voller Tücken. Bei den Beispielsskripten, die man im Internet findet, sind Fehler oder Schwachstellen enthalten, die sich oft nicht sofort bemerkbar machen. So passiert es oft, dass einzelne Empfänger keine oder verhackstückte email-Anhänge erhalten, was zu einem Dauerthema in Diskussionsforen führt. Ein sehr schönes Beispiel für die Komplexität:

Beispiel: http://forum.de.selfhtml.org/archiv/2006/2/t123122/

Problem ist oft der "Boundery", der benötigte Trenner, der die E-Mail-Abschnitte voneinander trennt. Er wirdin den gängigen Beispielen zum Teil mit "--", z.T. mit "==" eingeleitet:

$mime_boundary = "==Multipart_Boundary_x{md5(time()}x";

oder

$mime_boundary = "--Multipart_Boundary_x{md5(time()}x";

Da der Trenner aber in der email vorkommen könnte, was schädlich wäre, müsste eine entsprechende Prüfung durchgeführt werden, genaugenommen: Es muß auf

"\n--$mime_boundary\r\n"

geprüft werden. Dass die Skripten trotzdem funktionieren, scheint daran zu liegen, dass ein solches Vorkommen sehr selten ist.

Empfohlen wird auch noch die Verwendung eines Zeichens, das nicht vorkommen kann, z.B. "=_"

Zitat Zeile 1146 aus Spezifikation RFC 2045

   Since the hyphen character ("-") may be represented as itself in the
   Quoted-Printable encoding, care must be taken, when encapsulating a
   quoted-printable encoded body inside one or more multipart entities,
   to ensure that the boundary delimiter does not appear anywhere in the
   encoded body.  (A good strategy is to choose a boundary that includes
   a character sequence such as "=_" which can never appear in a
   quoted-printable body.  See the definition of multipart messages in
   RFC 2046.)
 

 


Fazit: Von dritten übernommene Skript-Routinen funktionieren in der Regel, es kommt aber vor, dass es aus unerklärlichen Gründen bei einzelnen mails oder bei einzelne Empfänger zu Problemen kommt.

Empfehlenswert ist die Verwendung einer Klasse, in der diese Technik ausgereift ist.  Die PEAR-Klasse ist etwas aufwändig. Daneben gibt es noch die Class "PHPMAiler" von http://phpmailer.codeworxtech.com (scheint das einfachste zu sein) und HTML Mime Mail for PHP von phpguru.org.

Empfohlene fertige Lösungen

phpmailer und/oder PEAR::Mail_Mime

Damit erzeugt man standardkonforme MIME-Mails, in die man Anhänge einfügen kann.

Homepage von PHPMailer

http://phpmailer.codeworxtech.com/index.php (Stand: Februar 2008)

 

PHPMailer NEW Versions released 10 November 2008!
a powerful email transport class with a big features and small footprint that is simple to use and integrate into your own software. ... more
 
PHPMailer-FE NEW Version 4.0 released 23 January 2009!
a form-to-email tool that uses PHPMailer to send rich format emails from the data in your forms (including attachments). Version 4.0 also adds support for Flash forms (including return code). NEW SUPPORT FORUM! (see tips section for examples on using plugin architecture)
Form hacks are increasing in frequency. We've put an article to gether with a comprehensive strategy. From the article, you can download our sample forms and Javascript to help you deal with potential hacks. ... more
 
PHPMailer-ML NEW Upgrade released 12 January 2009!
a mailing list manager and newsletter manager that uses PHPMailer to send text and/or HTML emails to an MySQL mailing list. We even include a form you can use on your website to sign up subscribers (double blind opt-in). New release on January 12 2008 (v1.2) includes enhanced subscribe form with IP2Country. ... more
 
PHPMailer-BMH NEW! NOW RELEASED!
PHPMailer-BMH (Bounce Mail Handler) v5.0.0 for PHP5 is now released with features that include: fast processing ... more
 
Tips and Tools
The "Tips" section is is our latest effort to put some real-world tips in your hands ... we have super tips like how to pause execution of your script, extend execution time of your script, strategies to get your emails past spam checkers, and specifications for popular servers. ... more

 Download direkt:

» PHPMailer for PHP4
» PHPMailer for PHP5/6
» PHPMailer-FE (Form2Email)
» PHPMailer-ML
» PHPMailer-BMH

Projektseite auf sourceforge: http://sourceforge.net/projects/phpmailer/


Skriptbeispiel (Ausschnitt aus einem backupskript)

dump ist in einer Datei (Pfad hierzu: $log_path)


    $headers = "From: " . $EMAIL_FROM . " <root@localhost>";
    // Generate a boundary string
    $rnd_str = md5(time());
    $mime_boundary = "==Multipart_Boundary_x{$rnd_str}x";

    // Add headers for file attachment
    $headers .= "\nMIME-Version: 1.0\n" .
        "Content-Type: multipart/mixed;\n" .
        " boundary=\"{$mime_boundary}\"";

    // Add a multipart boundary above the plain message
    /* Boundary trennt jeweils die E-Mail-Abschnitte voneinander */
    $body = "This is a multi-part message in MIME format.\n\n" .
        "--{$mime_boundary}\n" .
        "Content-Type: text/plain; charset=\"iso-8859-1\"\n" .
        "Content-Transfer-Encoding: 7bit\n\n" .
        file_get_contents($log_path) . "\n\n";

    // make Base64 encoding for file data

   $data = chunk_split(base64_encode($data,76,"\n"));

// Anmerkung Burkes Februa 2009:

// Original:     $data = chunk_split(base64_encode($attachement);
// aber gemäß einem Tipp in einem Aufsatz auf http://forum.de.selfhtml.org/archiv/2006/2/t123122/
// In Base-64 sollte nicht die Voreinstellung von Chunk_Split für das Zeilenschaltungszeichen benutzt werden, sondern "\n"
// $attach_data = chunk_split(base64_encode($attach_data,76,"\n"));
// Irgendwo in der RFC steht auch versteckt drin, dass Base-64-codierte Teile nur mit einem einfachen Linefeed, und nicht mit einem CRLF, so wie das bei den Headern eigentlich vorgeschrieben ist, umgebrochen werden sollen.


    // Add file attachment to the message
    $body .= "--{$mime_boundary}\n" .
        "Content-Type: {$backup_mime};\n" .
        " name=\"{$BACKUP_NAME}\"\n" .
        "Content-Disposition: attachment;\n" .
        " filename=\"{$BACKUP_NAME}\"\n" .
        "Content-Transfer-Encoding: base64\n\n" .
        $data . "\n\n" .
        "--{$mime_boundary}--\n";

    $res = mail( $EMAIL_ADDR, $EMAIL_SUBJECT, $body, $headers );
    if ( !$res ) {
        error( true, 'FAILED to email mysql dumps.' );
    }

 

Google-Suche

Google

Geldverdienst mit Webseite