<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://wiki.stephanschlegel.de/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=178.7.132.100</id>
	<title>Wikizone - Benutzerbeiträge [de]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.stephanschlegel.de/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=178.7.132.100"/>
	<link rel="alternate" type="text/html" href="https://wiki.stephanschlegel.de/index.php?title=Spezial:Beitr%C3%A4ge/178.7.132.100"/>
	<updated>2026-05-06T19:49:38Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.35.14</generator>
	<entry>
		<id>https://wiki.stephanschlegel.de/index.php?title=PHP_-_E-Mail_versenden&amp;diff=19053</id>
		<title>PHP - E-Mail versenden</title>
		<link rel="alternate" type="text/html" href="https://wiki.stephanschlegel.de/index.php?title=PHP_-_E-Mail_versenden&amp;diff=19053"/>
		<updated>2012-03-13T10:43:08Z</updated>

		<summary type="html">&lt;p&gt;178.7.132.100: /* E-Mail mit CSS und Anhang */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Links&lt;br /&gt;
&lt;br /&gt;
http://www.phpbuddy.eu/emails-mit-php-versenden.html?start=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Einfache Text E-Mail mit Template ===&lt;br /&gt;
Einfache Text Email&lt;br /&gt;
&lt;br /&gt;
Zuerst das Listing unserer Template Datei mailbody.txt&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Soeben ist eine Nachricht von ###NAME### eingetroffen.&lt;br /&gt;
Als Antwortadresse wurde ###EMAIL### angegeben.&lt;br /&gt;
Die Nachricht die gesendet wurde:&lt;br /&gt;
###NACHRICHT###&lt;br /&gt;
&lt;br /&gt;
Wie man unschwer erkennt, ist das ganz normaler und schlichter Text. Lediglich die Platzhalter darin fallen auf. Diese Platzhalter korrespondieren in unserem Script mit den Benutzereingaben und werden in unserem Script durch diese ersetzt.&lt;br /&gt;
Dadurch das wir den Text, der später per Email an uns geschickt wird, in einer eigenen Datei ablegen, können wir den Text schnell und flexibel beliebig verändern und erweitern. Da es sich hierbei um einen Mailer handelt der nur reinen Text verschickt, müssen wir auf jegliche Art von Formatierungen verzichten.&lt;br /&gt;
&lt;br /&gt;
Bisher haben wir das HTML-Formular, die Funktionen und das Mail Template kennengelernt, fehlt nur noch das Hauptscript, dass wir uns gleich mal vorknöpfen.&lt;br /&gt;
&lt;br /&gt;
Listing der Datei mail.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
 &lt;br /&gt;
header( &amp;#039;Content-Type: text/html; charset=utf-8&amp;#039; );&lt;br /&gt;
 &lt;br /&gt;
// Empfänger Email&lt;br /&gt;
$empfaenger = &amp;#039;max.mustermann@domain.tld&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
// Prüfen ob das Formular abgeschickt wurde&lt;br /&gt;
if (isset($_POST[&amp;#039;senden&amp;#039;]))&lt;br /&gt;
{&lt;br /&gt;
    // Funktionen einbinden&lt;br /&gt;
    include( &amp;#039;funktionen.inc.php&amp;#039; );&lt;br /&gt;
 &lt;br /&gt;
    // Benutzereingaben bereinigen und auf Injection prüfen&lt;br /&gt;
    cleanInput();&lt;br /&gt;
 &lt;br /&gt;
    // Name prüfen&lt;br /&gt;
    $name = checkName( $_POST[&amp;#039;name&amp;#039;] );&lt;br /&gt;
    // Email prüfen&lt;br /&gt;
    $email = checkEmail( $_POST[&amp;#039;email&amp;#039;] );&lt;br /&gt;
    // Betreff und Nachricht prüfen&lt;br /&gt;
    if ((strlen( $_POST[&amp;#039;betreff&amp;#039;] ) &amp;lt; 5) || (strlen( $_POST[&amp;#039;nachricht&amp;#039;] ) &amp;lt; 5))&lt;br /&gt;
    {&lt;br /&gt;
        die( &amp;#039;Bitte füllen Sie alle Felder aus!&amp;#039; );&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        $betreff   = $_POST[&amp;#039;betreff&amp;#039;];&lt;br /&gt;
        $nachricht = $_POST[&amp;#039;nachricht&amp;#039;];&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    // --------------------------------------------------------------------------------&lt;br /&gt;
    // Wurde das Script bisher nicht abgebrochen, wurde das Formular korrekt ausgefüllt&lt;br /&gt;
    // --------------------------------------------------------------------------------&lt;br /&gt;
 &lt;br /&gt;
    // Template mit dem Mailbody laden und für den Versand vorbereiten&lt;br /&gt;
    $mailbody = file_get_contents( &amp;#039;mailbody.txt&amp;#039; );&lt;br /&gt;
    // Platzhalter mit den Benutzereingaben ersetzen&lt;br /&gt;
    $mailbody = str_replace( &amp;#039;###NAME###&amp;#039;, htmlspecialchars( $name ), $mailbody );&lt;br /&gt;
    $mailbody = str_replace( &amp;#039;###EMAIL###&amp;#039;, $email, $mailbody );&lt;br /&gt;
    $mailbody = str_replace( &amp;#039;###NACHRICHT###&amp;#039;, htmlspecialchars( $nachricht ), $mailbody );&lt;br /&gt;
 &lt;br /&gt;
    // Mail Header erstellen&lt;br /&gt;
    $mailheader  = &amp;quot;From: PHP Email Tutorial&amp;lt;noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Reply-To: &amp;quot; .$name. &amp;quot;&amp;lt;&amp;quot; .$email. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Return-Path: noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;MIME-Version: 1.0\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Type: text/plain; charset=UTF-8\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Transfer-Encoding: 7bit\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Message-ID: &amp;lt;&amp;quot; .time(). &amp;quot; noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;X-Mailer: PHP v&amp;quot; .phpversion(). &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    // Email versenden&lt;br /&gt;
    if (@mail( $empfaenger, htmlspecialchars( $betreff ), $mailbody, $mailheader ))&lt;br /&gt;
    {&lt;br /&gt;
        // Bei erfolgreichem Versand Danke-Seite anzeigen&lt;br /&gt;
        echo &amp;#039;Danke, die Email wurde verschickt!&amp;#039;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das sieht im ersten Moment mehr und wilder aus, als es das eigentlich ist. Der obere Teil ist schnell erklärt. Zunächst setzen wir die Email des Empfängers, der idR wir selbst sind. Dann wird geprüft ob das Formular überhaupt abgeschickt wurde und wenn dem so ist, binden wir die benötigten Funktionen ein und überprüfen die Benutzereingaben.&lt;br /&gt;
&lt;br /&gt;
Mit den Zeilen ...&lt;br /&gt;
&lt;br /&gt;
    // Template mit dem Mailbody laden und für den Versand vorbereiten&lt;br /&gt;
    $mailbody = file_get_contents( &amp;#039;mailbody.txt&amp;#039; );&lt;br /&gt;
    // Platzhalter mit den Benutzereingaben ersetzen&lt;br /&gt;
    $mailbody = str_replace( &amp;#039;###NAME###&amp;#039;, htmlspecialchars( $name ), $mailbody );&lt;br /&gt;
    $mailbody = str_replace( &amp;#039;###EMAIL###&amp;#039;, $email, $mailbody );&lt;br /&gt;
    $mailbody = str_replace( &amp;#039;###NACHRICHT###&amp;#039;, htmlspecialchars( $nachricht ), $mailbody );&lt;br /&gt;
&lt;br /&gt;
... laden wir das Mail Template (file_get_contents) und ersetzen mit einfachen str_replace Funktionen die Platzhalter. Auch wenn wir bereits auf mögliche Injections geprüft haben, entschärfen wir dennoch die Eingaben mit htmlspecialchars, damit uns niemand etwas unterschiebt. Bei der Email ist das nicht nötig, da diese sonst nicht durch den Filter gekommen wäre.&lt;br /&gt;
&lt;br /&gt;
Jetzt kommen wir zu dem wichtigsten Teil, der ein erfolgreiches Versenden überhaupt erst möglich macht: dem Mail Header.&lt;br /&gt;
&lt;br /&gt;
Der Mail Header ist der Kopf der Email, der alle relevanten und wichtigen Informationen über unsere Email enthält. Sehr sehr häufig sieht man in Scripts und Tutorials, dass hier lediglich das &amp;quot;From:&amp;quot; angegeben ist. Wenn nur diese Information angegeben ist, bleibt die Mail sehr häufig in einem Spamfilter hängen. Kein Mensch würde auf die Idee kommen einen echten Brief zu verschicken und als Beschreibung auf dem Brief nur einen Name angeben, ohne komplette Anschrift und Absenderadresse. Wieso dann bei einer Email?!&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns also an wie ein Header aussieht, der die wichtigsten Angaben enthält:&lt;br /&gt;
&lt;br /&gt;
    $mailheader  = &amp;quot;From: PHP Email Tutorial&amp;lt;noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Reply-To: &amp;quot; .$name. &amp;quot;&amp;lt;&amp;quot; .$email. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Return-Path: noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;MIME-Version: 1.0\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Type: text/plain; charset=UTF-8\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Transfer-Encoding: 7bit\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Message-ID: &amp;lt;&amp;quot; .time(). &amp;quot; noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;X-Mailer: PHP v&amp;quot; .phpversion(). &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
Die Steuerungzeichen &amp;quot;\r\n&amp;quot; entsprechen einen Wagenrücklauf und Zeilenvorschub oder anders ausgedrückt, ein Zeilenumbruch. Diese Steuerungzeichen sind betriebssystemabhängig und müssen ggfs. angepasst werden. Auf Linux würde man z.B. nur &amp;quot;\n&amp;quot; verwenden. Schauen wir uns nun die anderen angaben an:&lt;br /&gt;
&lt;br /&gt;
    From - Das ist die Absendeadresse und der dazugehörige Name. Es ist üblich diesen in der Form Name anzugeben. Das ist die absolute Minimumangabe für inen Mailheader. Fehlt das From, wird der Versand der Mail fehlschlagen.&lt;br /&gt;
    Reply-To - Das Format kann entweder nur eine Email Adresse sein, oder man wählt das Format wir bei From. Dieses Feld ist die Antwortadresse an die die Mail geschickt wird, wenn wir im Mail Client auf antworten klicken.&lt;br /&gt;
    Return-Path - Konnte die Mail nicht zugestellt werden, wird dies an diese Adresse gemeldet.&lt;br /&gt;
    MIME-Version - Entspricht dem MIME Typ der Mail.&lt;br /&gt;
    Content-Type - Das ist die Information die dem Mail Client mitteilt, um welche Art Mail es sich handelt und welcher Zeichensatz zur Darstellung benutzt werden soll.&lt;br /&gt;
    Content-Transfer-Encoding - Dies beschreibt die Art der Übertragung und wie sowohl Mailserver, als auch Email Clients diese Mail interpretieren. 7bit ist die kleinste Form, die maximal mögliche Kompatibilität ermöglicht. Beim 7bit ASCII Zeichensatz können die ersten 128 zeichen der ASCII Tabelle dargestellt werden. Zeichen wie deutsche Umlaute sind darin nicht vorgesehen. Bei der 8bit Übertragung können bis zu 256 zeichen dargestellt werden. Ältere Mailerver, so liest man, verstehen nur 7bit und verwerfen Anfragen die mit 8bit übertragen werden sollen. Anders ausgedrückt, es kann passieren das die Mail nicht ankommt. Ich persönlich hatte damit allerdings noch nie Probleme und die 7bit &amp;quot;Zwangsangabe&amp;quot; scheint veraltet zu sein.&lt;br /&gt;
    Message-ID - Die Message ID ist einmalig, bzw. sollte es sein, wodurch die Mail eindeutig zugeordnet werden kann.&lt;br /&gt;
    X-Mailer - Beschreibt den Client der die Mail versendet hat. In unserem Fall geben wir die PHP Version an, damit Mailserver auf der Route wissen, dass diese Mail mit PHP verschickt wurde.&lt;br /&gt;
&lt;br /&gt;
Es gibt noch weitere Felder und Varianten, die uns aber im moment nicht kümmern. Im Abschnitt Mail mit Anhang werden wir noch einen etwas anderen Header kennen lernen.&lt;br /&gt;
Speziell die letzten beiden Angaben (Message ID und X_Mailer) im Header oben sind sehr wichtige Informationen. Fehlen diese Angaben, ist die Wahrscheinlichkeit sehr hoch, dass die Mail niemals beim Empfänger ankommen wird, weil die Mail irgendwo unterwegs in einem Spamfilter hängen bleibt und nicht weitergeleitet wird!&lt;br /&gt;
&lt;br /&gt;
Falls also eine Mail nicht ankommt, liegt das in den aller meisten Fällen entweder am Transfer-Encoding (7bit oder 8bit) oder an fehlenden Absendeangaben!&lt;br /&gt;
&lt;br /&gt;
Der Rest des Scripts ist sehr einfach, weil hier einfach nur noch die Mail verschickt wird.&lt;br /&gt;
&lt;br /&gt;
    if (@mail( $empfaenger, htmlspecialchars( $betreff ), $mailbody, $mailheader ))&lt;br /&gt;
    {&lt;br /&gt;
        // Bei erfolgreichem Versand Danke-Seite anzeigen&lt;br /&gt;
        echo &amp;#039;Danke, die Email wurde verschickt!&amp;#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Die mail-Funktion kennt noch einen 5. Parameter auf den ich jetzt nicht eingehen werde, weil dieser nur in den seltensten Fällen unterstützt wird. Wer mehr darüber erfahren möchte kann sich darüber in der Online-Doku informieren. Die mail-Funktion selbst liefert entweder TRUE oder FALSE zurück. Bei einem FALSE konnte die Mail nicht für den Versand übergeben werden und wir können entsprechend darauf reagieren. Im Falle von TRUE heisst das zwar das die Mail für den Versand angenommen wurde, aber es ist nicht prüfbar ob die Mail auch tatsächlich beim Empfänger ankam! Einige Gründe dafür stehen weiter oben. Wurde die Mail für den Versand akzeptiert, können wir darauf angemessen reagieren, indem wir den Besucher zu einer Danke-Seite weiterleiten oder, was weiter unter gezeigt wird, dem Benutzer eine Empfangsbestätigung, respektive Kopie der Mail an seine Adresse schicken.&lt;br /&gt;
&lt;br /&gt;
Soweit so gut. Dieser Abschnitt fiel etwas länger aus, weil ich die prinzipielle Funktionsweise und den Header beschrieben habe. Die nachfolgenden Beispiele sind über große Strecken identisch, deswegen spare ich mir dort die Erklärungen und gehe nur auf die abweichenden Passagen ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== E-Mail mit CSS Formatierung ===&lt;br /&gt;
&lt;br /&gt;
Eine Email im HTML Format zu senden ist im Grunde genommen nichts anderes, als eine einzelne Webseite per Email zu verschicken. Wir haben also mehr oder weniger freie Hand was die Gestaltung angeht, solange wir uns an die HTML und CSS Richtlinien halten. Das wird sofort ersichtlicht, wenn man das Template für die Email sieht.&lt;br /&gt;
&lt;br /&gt;
Listing der Datei mailbody.txt&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;quot; &amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html xmlns=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot; xml:lang=&amp;quot;de&amp;quot; lang=&amp;quot;de&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=utf-8&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Email als HTML&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt;&lt;br /&gt;
body { font: normal 12px Verdana, Arial, Helvetica, sans-serif; }&lt;br /&gt;
a { color: blue; text-decoration: none; }&lt;br /&gt;
h2 { font-size: 16px; font-weight: bold; }&lt;br /&gt;
.gruen { color: green; }&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;h2&amp;gt;Soeben ist eine Nachricht von &amp;lt;span class=&amp;quot;gruen&amp;quot;&amp;gt;###NAME###&amp;lt;/span&amp;gt; eingetroffen.&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Als Antwortadresse wurde &amp;lt;a href=&amp;quot;mailto:###EMAIL###&amp;quot;&amp;gt;###EMAIL###&amp;lt;/a&amp;gt; angegeben.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Die Nachricht die gesendet wurde lautet:&amp;lt;br /&amp;gt;&lt;br /&gt;
###NACHRICHT###&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Template besteht aus einer normalen HTML Datei mit etwas CSS. Auch hier treffen wir wieder unsere Platzhalter, die durch die Benutzereingaben ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
Die Datei funktionen.inc.php ist identisch mit wie beim vorherigen Beispiel. Auch die mail.php weicht nur minimal vom letzten Beispiel ab - das aber mit großer Wirkung!&lt;br /&gt;
Die erste Abweichung findet in der Zeile zum ersetzen des Platzhalters für die Nachricht statt.&lt;br /&gt;
&lt;br /&gt;
 $mailbody = str_replace( &amp;#039;###NACHRICHT###&amp;#039;, nl2br( htmlspecialchars( $nachricht ) ), $mailbody );&lt;br /&gt;
&lt;br /&gt;
Ergänzt wurde hier die Funktion nl2br. Diese Funktion bewirkt, dass das Steuerungzeichen für einen Zeilenumbruch (\n) in ein HTML-konformes Break (&amp;lt;br /&amp;gt;) umgewandelt wird. Ohne diese Funktion hätten wir bei der Ausgabe nur eine laaaange Zeile Text ohne neue Absätze und Umbrüche.&lt;br /&gt;
&lt;br /&gt;
Die nächsten beiden Veränderungen finden im Mail Header statt. Da wird nun ja keinen reinen Text, sondern HTML verschicken, muß natürlich der Content-Type angepasst werden. Ebenso ändern wir das Transfer-Encoding auf 8bit. Hier die beiden geänderten Zeilen:&lt;br /&gt;
&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Type: text/html; charset=UTF-8\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Transfer-Encoding: 8bit\r\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
That&amp;#039;s it!&lt;br /&gt;
Diese kleinen Veränderungen haben eine solch große Auswirkung auf die Art der Darstellung!&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis im Mail Client:&lt;br /&gt;
&lt;br /&gt;
(Deutlich zu sehen das die H2-Überschrift sich absetzt und auch der Name durch das CSS farblich hervorgehoben wird)&lt;br /&gt;
&lt;br /&gt;
Vermutlich stand jeder angehende Programmierer schon mal an dieser Stelle. Voller Stolz blickt man in sein Postfach, wo die erste Mail vom eigenen Formmailer eingetroffen ist. Dann denkt man sich: &amp;quot;Das war ja einfach, mit nur so wenigen Zeilen Code so ein Ergebnis zu erzielen. Wie schwer kann es da schon sein auch eine Datei mitzuschicken?!&amp;quot;.&lt;br /&gt;
Angesichts der oben gezeigten Beispiele, und wie minimal der Unterschied zwischen Text Mail und HTML Mail ist, neigt man dazu zu denken, dass dies mit einem Dateianhang ebenso einfach ist.&lt;br /&gt;
&lt;br /&gt;
Tja, leider ist dem nicht so. Das senden von Dateianhänge ist erheblich aufwändiger als das senden einer Text/HTML Mail. Das Formular ist abweichend, der Mail Header ist abweichend, der Mail Body muß in einzelne Teilbereiche getrennt werden, Dateianhänge müssen Richtlinien beachten, was die Zeilenlänge und die Art der Zeichen innerhalb der Mail angeht.&lt;br /&gt;
Glücklicherweise hilft uns PHP bei den meisten Sachen und deshalb werden wir auch dieses Problem meistern. :)&lt;br /&gt;
&lt;br /&gt;
=== E-Mail mit CSS und Anhang ===&lt;br /&gt;
Todo Quelle siehe oben (2012-03)&lt;br /&gt;
&lt;br /&gt;
HTML Email mit CSS Formatierung und Dateianhang&lt;br /&gt;
&lt;br /&gt;
Da wir eine Datei mit der Mail verschicken möchten, muß das Formular natürlich dahingehend erweitert werden, dass ein Upload auch möglich ist. In unserem Beispiel möchten wir eine JPG datei anhängen und erlauben auch nur das hochladen dieses Bildtyps.&lt;br /&gt;
Die Template Datei ist identisch zum vorherigen HTML Beispiel. In der Datei funktionen.inc.php fügen wir aber eine weitere Funktion hinzu, die für uns prüft, ob eine Datei hochgeladen wurde und ob es sich dabei um eine JPG Datei handelt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function checkFile()&lt;br /&gt;
{&lt;br /&gt;
    if ($_FILES[&amp;#039;datei&amp;#039;][&amp;#039;error&amp;#039;] == 0 &amp;amp;&amp;amp;&lt;br /&gt;
        $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;type&amp;#039;] == &amp;#039;image/jpeg&amp;#039;)&lt;br /&gt;
    {&lt;br /&gt;
        return $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;name&amp;#039;];&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        die( &amp;#039;Bitte eine gültige JPG Datei anhängen!&amp;#039; );&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der Datei mail.php wird sich nun einiges ändern. Zunächst erweitern wir die einleitende Abfrage dahingehend, dass wir feststellen ob auch eine Datei angehängt wurde ...&lt;br /&gt;
&lt;br /&gt;
 if (isset($_POST[&amp;#039;senden&amp;#039;]) &amp;amp;&amp;amp; $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;size&amp;#039;] &amp;gt; 0)&lt;br /&gt;
&lt;br /&gt;
... und fügen ebenso den Aufruf für die neue Funktion hinzu, die prüft ob ein JPG hochgeladen wurde:&lt;br /&gt;
&lt;br /&gt;
 $uploadname = checkFile();&lt;br /&gt;
&lt;br /&gt;
Das weitere Listing der Datei mail.php sieht wie folgt aus:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // Template mit dem Mailbody laden&lt;br /&gt;
    $template = file_get_contents( &amp;#039;mailbody.txt&amp;#039; );&lt;br /&gt;
    // Trenner für den Anhang&lt;br /&gt;
    $trenner = md5( time() );&lt;br /&gt;
 &lt;br /&gt;
    // Platzhalter mit den Benutzereingaben ersetzen&lt;br /&gt;
    $template = str_replace( &amp;#039;###NAME###&amp;#039;, htmlspecialchars( $name ), $template );&lt;br /&gt;
    $template = str_replace( &amp;#039;###EMAIL###&amp;#039;, $email, $template );&lt;br /&gt;
    $template = str_replace( &amp;#039;###NACHRICHT###&amp;#039;, nl2br( htmlspecialchars( $nachricht ) ), $template );&lt;br /&gt;
 &lt;br /&gt;
    // Mail Header erstellen&lt;br /&gt;
    $mailheader .= &amp;quot;Reply-To: &amp;quot; .$name. &amp;quot;&amp;lt;&amp;quot; .$email. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Return-Path: noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Message-ID: &amp;lt;&amp;quot; .time(). &amp;quot; noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;X-Mailer: PHP v&amp;quot; .phpversion(). &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;From: PHP Email Tutorial&amp;lt;noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;MIME-Version: 1.0\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Type: multipart/mixed;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot; boundary = &amp;quot; .$trenner;&lt;br /&gt;
    $mailheader .= &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    // Mailbody vorbereiten&lt;br /&gt;
    $mailbody  = &amp;quot;This is a multi-part message in MIME format\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;--&amp;quot; .$trenner. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Type: text/html; charset=UTF-8\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Transfer-Encoding: 8bit\r\n\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= $template. &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    // Anhang anfügen&lt;br /&gt;
    $mailbody .= &amp;quot;--&amp;quot; .$trenner. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Type: image/jpeg; name=\&amp;quot;&amp;quot; .$uploadname. &amp;quot;\&amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Transfer-Encoding: base64\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Disposition: attachment; filename=\&amp;quot;&amp;quot; .$uploadname. &amp;quot;\&amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= chunk_split( base64_encode( file_get_contents( $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;tmp_name&amp;#039;] ) ) );&lt;br /&gt;
    $mailbody .= &amp;quot;\n&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    // Email versenden&lt;br /&gt;
    if (@mail( $empfaenger, htmlspecialchars( $betreff ), $mailbody, $mailheader ))&lt;br /&gt;
    {&lt;br /&gt;
        // Bei erfolgreichem Versand Danke-Seite anzeigen&lt;br /&gt;
        echo &amp;#039;Danke, die Email wurde verschickt!&amp;#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen auf den ersten Blick, dass dieser Code ganz anders aussieht als das vorherige Beispiel. Gehen wir den Code mal der Reihe nach durch, um etwas Licht in&amp;#039;s Dunkel zu bringen.&lt;br /&gt;
&lt;br /&gt;
Im oberen Bereich erzeugen wir einen eindeutigen String, den wir zum trennen der verschiedenen Teilbereiche der Mail verwenden werden:&lt;br /&gt;
&lt;br /&gt;
 $trenner = md5( time() );&lt;br /&gt;
&lt;br /&gt;
Der erste Teil des Mail Header ist uns bereits bekannt, aber beim Content-Type benötigen wir nun eine andere Angabe.&lt;br /&gt;
&lt;br /&gt;
 $mailheader .= &amp;quot;Content-Type: multipart/mixed;\r\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
Dieser Content-Type ähnelt der Angabe &amp;quot;multipart/form-data&amp;quot; in einem HTML Formular, wenn wir dort ebenfalls gemischte Inhalte haben, nämlich Text und Dateien. Damit der Mail Client nun weiß an welchen Stellen im gesendeten Quellcode er Inhalte trennen muß, teilen wir im Header den boundary-String mit.&lt;br /&gt;
&lt;br /&gt;
An dieser Stelle möchte ich noch auf 2 wichtige Dinge hinweisen. Das Leerzeichen vor dem &amp;quot;boundary&amp;quot; im Header ist kein Versehen! Es kann tatsächlich dazu führen das eine Mail nicht korrekt dargestellt wird, wenn dieses Leerzeichen fehlt. Ebenso ist es wichtig, dass die &amp;quot;From&amp;quot;-Angabe unmittelbar vor der &amp;quot;MIME-Version&amp;quot; und dem &amp;quot;Content-Type&amp;quot; steht. Vertauscht man die Reihenfolge der Header Angabe, führt das z.B. bei mir dazu, dass ich im Thunderbird nur eine leere Seite als Mail angezeigt bekomme, obwohl der komplette Mail Inhalt im Quelltext einsehbar ist.&lt;br /&gt;
&lt;br /&gt;
Die nächste Zeile ...&lt;br /&gt;
&lt;br /&gt;
 $mailbody  = &amp;quot;This is a multi-part message in MIME format\r\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
... steht vor der Nachricht im Head Bereich in der Email. Sie scheint nicht zwingend erforderlich zu sein, aber Mail Clients fügen diese ebenfalls hinzu, wenn man mit z.B. Thunderbird eine Email verschickt. Ich vermute, dass dies aus Gründen der Kompatibilität zu einigen Mail Server geschieht.&lt;br /&gt;
&lt;br /&gt;
Nun folgt der erste Teil unserer Email, der Text.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    $mailbody .= &amp;quot;--&amp;quot; .$trenner. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Type: text/html; charset=UTF-8\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Transfer-Encoding: 8bit\r\n\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= $template. &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Durch den Trenner teilen wir dem Mail Client mit, dass zwischen diesem Trenner und dem nächsten Trenner, bzw. dem Ende der Mail, ein Teilabschnitt dieser Email steht. Damit der Client weiß um was es sich bei diesem Abschnitt handelt, teilen wir ihm das mithilfe des &amp;quot;Content-Type&amp;quot; und dem &amp;quot;Transfer-Encoding&amp;quot; mit. Durch die Angabe &amp;quot;text/html&amp;quot; weiß nun der Client, dass alles bis zum nächsten Trennen als HTML dargestellt werden soll.&lt;br /&gt;
&lt;br /&gt;
Der nächste Teilabschnitt der Mail ist unser Bild:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // Anhang anfügen&lt;br /&gt;
    $mailbody .= &amp;quot;--&amp;quot; .$trenner. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Type: image/jpeg; name=\&amp;quot;&amp;quot; .$uploadname. &amp;quot;\&amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Transfer-Encoding: base64\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Disposition: attachment; filename=\&amp;quot;&amp;quot; .$uploadname. &amp;quot;\&amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= chunk_split( base64_encode( file_get_contents( $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;tmp_name&amp;#039;] ) ) );&lt;br /&gt;
    $mailbody .= &amp;quot;\n&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wieder folgt zunächst der Trenner. Der Client stoppt seine HTML Ausgabe an dieser Position und wird ab diesem Punkt ausgeben, was ihm durch den &amp;quot;Content-Type&amp;quot; und das &amp;quot;Transfer-Encoding&amp;quot; aufgetragen wird. Wir sehen nun, dass wir als Content-Type eine JPG Datei ausgeben möchten. Der Name ergibt sich aus dem Rückgabewert der Funktion, die den Upload zuvor überprüft hat. Als Transfer-Encoding wird &amp;quot;base64&amp;quot; angegeben. Diese Angabe ist überaus wichtig um eine korrekte Übertragung der Daten zu gewährleisten. Mit der Angabe &amp;quot;Content-Disposition: attachment;&amp;quot; legen wir fest, dass der Anhang wirklich an die Mail angehängt wird. Eine andere Möglichkeit wäre hier das Einbetten in den Mailtext, indem man als Content-Disposition ein &amp;quot;inline&amp;quot; angibt. Die nächste Zeile ist ziemlich tricky:&lt;br /&gt;
&lt;br /&gt;
 $mailbody .= chunk_split( base64_encode( file_get_contents( $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;tmp_name&amp;#039;] ) ) );&lt;br /&gt;
&lt;br /&gt;
Arbeiten wir uns mal von Innen nach Außen durch, weil hier mehrere Funktionen verschachtelt sind. Mit file_get_contents wird eine Datei als String eingelesen. Dies ist hier möglich, weil diese Funktion seit PHP 4.3 binary safe ist. Als einzulesender Dateiname nehmen wir hier den Name der temporären datei, die durch den Upload auf dem Server gelandet ist. Diese Datei steht nur zu genau diesem Zeitpunkt zur Verfügung. Sobald das Script beendet wird oder eine andere Seite geladen wird, existiert diese Datei nicht mehr. Möchte man diese Datei erst zu einem späteren Zeitpunkt verarbeiten, muß man diese zunächst mit move_uploaded_file an eine andere Position kopieren.&lt;br /&gt;
Da wir nun die Bilddatei als String eingelesen haben, wird er mit base64_encode umgewandelt, damit die Datei beschädigt wird, falls es nicht möglich ist die Mail als 8bit zu übertragen. Es wird also aus Gründen der Kompatibilität gemacht. Anschließend wird der String mit chunk_split so aufbereitet, dass die Zeilenlänge 76 Zeichen nicht übersteigt.&lt;br /&gt;
&lt;br /&gt;
Das war&amp;#039;s! Die Daten können nun wieder mit der mail-Funktion versendet werden. Sollte man mehr als eine Datei anhängen wollen, kann man den letzten Schritt beliebig oft wiederholen. Erst Trenner setzen, dann Art der Daten und Übertragungsmodus angeben, die Datei anhängen, fertig.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== E-Mail mit Empfangsbestätigung ===&lt;br /&gt;
&lt;br /&gt;
Eine Empfangsbestätigung verschicken&lt;br /&gt;
&lt;br /&gt;
Das ist genauso einfach wie das verschicken einer ganz einfachen Textmail. Wie wir ja bereits gehört haben, gibt die mail-Funktion bei Erfolg ein TRUE zurück. Damit können wir also feststellen, ob die Nachricht des Benutzers an uns übermittelt wurde und falls ja, schicken wir ihm eine Mail als Bestätigung. Das sieht in etwa so aus:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    if (@mail( $empfaenger, htmlspecialchars( $betreff ), $mailbody, $mailheader ))&lt;br /&gt;
    {&lt;br /&gt;
        // Bei erfolgreichem Versand Danke-Seite anzeigen&lt;br /&gt;
        $mailheader  = &amp;quot;From: Firma Max Mustermann&amp;lt;mustermann@domain.tld&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
        $mailheader .= &amp;quot;Reply-To: Firma Max Mustermann&amp;lt;mustermann@domain.tld&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
        $mailheader .= &amp;quot;Return-Path: noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
        $mailheader .= &amp;quot;MIME-Version: 1.0\r\n&amp;quot;;&lt;br /&gt;
        $mailheader .= &amp;quot;Content-Type: text/plain; charset=UTF-8\r\n&amp;quot;;&lt;br /&gt;
        $mailheader .= &amp;quot;Content-Transfer-Encoding: 7bit\r\n&amp;quot;;&lt;br /&gt;
        $mailheader .= &amp;quot;Message-ID: &amp;lt;&amp;quot; .time(). &amp;quot; noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
        $mailheader .= &amp;quot;X-Mailer: PHP v&amp;quot; .phpversion(). &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
        // Inhalt der Bestätigung&lt;br /&gt;
        $mailbody = &amp;#039;Vielen Dank für Ihre Email. Wir werden uns in Kürze bei Ihnen melden.&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
        // Bestätigung verschicken&lt;br /&gt;
        if (@mail( $email, &amp;quot;Die Firma Max Mustermann bedankt sich&amp;quot;, $mailbody, $mailheader ))&lt;br /&gt;
        {&lt;br /&gt;
            // Bestätigung wurde verschickt&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Das ist im Prinzip der selbe Code wie zuvor in der Text Mail. Es werden lediglich einige Kleinigkeiten im Mail Header angepasst, damit der Benutzer auch weiß, wer ihm schreibt und wohin er antworten kann.&lt;br /&gt;
&lt;br /&gt;
Damit sollten die meisten Fragen zum Thema &amp;quot;Wie versendet man eine Email mit PHP&amp;quot; geklärt sein. Wer Fragen oder Anregungen hat, kann sie gerne in diesem Thread stellen.&lt;/div&gt;</summary>
		<author><name>178.7.132.100</name></author>
	</entry>
	<entry>
		<id>https://wiki.stephanschlegel.de/index.php?title=PHP_-_E-Mail_versenden&amp;diff=19052</id>
		<title>PHP - E-Mail versenden</title>
		<link rel="alternate" type="text/html" href="https://wiki.stephanschlegel.de/index.php?title=PHP_-_E-Mail_versenden&amp;diff=19052"/>
		<updated>2012-03-13T10:42:32Z</updated>

		<summary type="html">&lt;p&gt;178.7.132.100: /* E-Mail mit CSS Formatierung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Links&lt;br /&gt;
&lt;br /&gt;
http://www.phpbuddy.eu/emails-mit-php-versenden.html?start=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Einfache Text E-Mail mit Template ===&lt;br /&gt;
Einfache Text Email&lt;br /&gt;
&lt;br /&gt;
Zuerst das Listing unserer Template Datei mailbody.txt&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Soeben ist eine Nachricht von ###NAME### eingetroffen.&lt;br /&gt;
Als Antwortadresse wurde ###EMAIL### angegeben.&lt;br /&gt;
Die Nachricht die gesendet wurde:&lt;br /&gt;
###NACHRICHT###&lt;br /&gt;
&lt;br /&gt;
Wie man unschwer erkennt, ist das ganz normaler und schlichter Text. Lediglich die Platzhalter darin fallen auf. Diese Platzhalter korrespondieren in unserem Script mit den Benutzereingaben und werden in unserem Script durch diese ersetzt.&lt;br /&gt;
Dadurch das wir den Text, der später per Email an uns geschickt wird, in einer eigenen Datei ablegen, können wir den Text schnell und flexibel beliebig verändern und erweitern. Da es sich hierbei um einen Mailer handelt der nur reinen Text verschickt, müssen wir auf jegliche Art von Formatierungen verzichten.&lt;br /&gt;
&lt;br /&gt;
Bisher haben wir das HTML-Formular, die Funktionen und das Mail Template kennengelernt, fehlt nur noch das Hauptscript, dass wir uns gleich mal vorknöpfen.&lt;br /&gt;
&lt;br /&gt;
Listing der Datei mail.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
 &lt;br /&gt;
header( &amp;#039;Content-Type: text/html; charset=utf-8&amp;#039; );&lt;br /&gt;
 &lt;br /&gt;
// Empfänger Email&lt;br /&gt;
$empfaenger = &amp;#039;max.mustermann@domain.tld&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
// Prüfen ob das Formular abgeschickt wurde&lt;br /&gt;
if (isset($_POST[&amp;#039;senden&amp;#039;]))&lt;br /&gt;
{&lt;br /&gt;
    // Funktionen einbinden&lt;br /&gt;
    include( &amp;#039;funktionen.inc.php&amp;#039; );&lt;br /&gt;
 &lt;br /&gt;
    // Benutzereingaben bereinigen und auf Injection prüfen&lt;br /&gt;
    cleanInput();&lt;br /&gt;
 &lt;br /&gt;
    // Name prüfen&lt;br /&gt;
    $name = checkName( $_POST[&amp;#039;name&amp;#039;] );&lt;br /&gt;
    // Email prüfen&lt;br /&gt;
    $email = checkEmail( $_POST[&amp;#039;email&amp;#039;] );&lt;br /&gt;
    // Betreff und Nachricht prüfen&lt;br /&gt;
    if ((strlen( $_POST[&amp;#039;betreff&amp;#039;] ) &amp;lt; 5) || (strlen( $_POST[&amp;#039;nachricht&amp;#039;] ) &amp;lt; 5))&lt;br /&gt;
    {&lt;br /&gt;
        die( &amp;#039;Bitte füllen Sie alle Felder aus!&amp;#039; );&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        $betreff   = $_POST[&amp;#039;betreff&amp;#039;];&lt;br /&gt;
        $nachricht = $_POST[&amp;#039;nachricht&amp;#039;];&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    // --------------------------------------------------------------------------------&lt;br /&gt;
    // Wurde das Script bisher nicht abgebrochen, wurde das Formular korrekt ausgefüllt&lt;br /&gt;
    // --------------------------------------------------------------------------------&lt;br /&gt;
 &lt;br /&gt;
    // Template mit dem Mailbody laden und für den Versand vorbereiten&lt;br /&gt;
    $mailbody = file_get_contents( &amp;#039;mailbody.txt&amp;#039; );&lt;br /&gt;
    // Platzhalter mit den Benutzereingaben ersetzen&lt;br /&gt;
    $mailbody = str_replace( &amp;#039;###NAME###&amp;#039;, htmlspecialchars( $name ), $mailbody );&lt;br /&gt;
    $mailbody = str_replace( &amp;#039;###EMAIL###&amp;#039;, $email, $mailbody );&lt;br /&gt;
    $mailbody = str_replace( &amp;#039;###NACHRICHT###&amp;#039;, htmlspecialchars( $nachricht ), $mailbody );&lt;br /&gt;
 &lt;br /&gt;
    // Mail Header erstellen&lt;br /&gt;
    $mailheader  = &amp;quot;From: PHP Email Tutorial&amp;lt;noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Reply-To: &amp;quot; .$name. &amp;quot;&amp;lt;&amp;quot; .$email. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Return-Path: noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;MIME-Version: 1.0\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Type: text/plain; charset=UTF-8\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Transfer-Encoding: 7bit\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Message-ID: &amp;lt;&amp;quot; .time(). &amp;quot; noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;X-Mailer: PHP v&amp;quot; .phpversion(). &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    // Email versenden&lt;br /&gt;
    if (@mail( $empfaenger, htmlspecialchars( $betreff ), $mailbody, $mailheader ))&lt;br /&gt;
    {&lt;br /&gt;
        // Bei erfolgreichem Versand Danke-Seite anzeigen&lt;br /&gt;
        echo &amp;#039;Danke, die Email wurde verschickt!&amp;#039;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das sieht im ersten Moment mehr und wilder aus, als es das eigentlich ist. Der obere Teil ist schnell erklärt. Zunächst setzen wir die Email des Empfängers, der idR wir selbst sind. Dann wird geprüft ob das Formular überhaupt abgeschickt wurde und wenn dem so ist, binden wir die benötigten Funktionen ein und überprüfen die Benutzereingaben.&lt;br /&gt;
&lt;br /&gt;
Mit den Zeilen ...&lt;br /&gt;
&lt;br /&gt;
    // Template mit dem Mailbody laden und für den Versand vorbereiten&lt;br /&gt;
    $mailbody = file_get_contents( &amp;#039;mailbody.txt&amp;#039; );&lt;br /&gt;
    // Platzhalter mit den Benutzereingaben ersetzen&lt;br /&gt;
    $mailbody = str_replace( &amp;#039;###NAME###&amp;#039;, htmlspecialchars( $name ), $mailbody );&lt;br /&gt;
    $mailbody = str_replace( &amp;#039;###EMAIL###&amp;#039;, $email, $mailbody );&lt;br /&gt;
    $mailbody = str_replace( &amp;#039;###NACHRICHT###&amp;#039;, htmlspecialchars( $nachricht ), $mailbody );&lt;br /&gt;
&lt;br /&gt;
... laden wir das Mail Template (file_get_contents) und ersetzen mit einfachen str_replace Funktionen die Platzhalter. Auch wenn wir bereits auf mögliche Injections geprüft haben, entschärfen wir dennoch die Eingaben mit htmlspecialchars, damit uns niemand etwas unterschiebt. Bei der Email ist das nicht nötig, da diese sonst nicht durch den Filter gekommen wäre.&lt;br /&gt;
&lt;br /&gt;
Jetzt kommen wir zu dem wichtigsten Teil, der ein erfolgreiches Versenden überhaupt erst möglich macht: dem Mail Header.&lt;br /&gt;
&lt;br /&gt;
Der Mail Header ist der Kopf der Email, der alle relevanten und wichtigen Informationen über unsere Email enthält. Sehr sehr häufig sieht man in Scripts und Tutorials, dass hier lediglich das &amp;quot;From:&amp;quot; angegeben ist. Wenn nur diese Information angegeben ist, bleibt die Mail sehr häufig in einem Spamfilter hängen. Kein Mensch würde auf die Idee kommen einen echten Brief zu verschicken und als Beschreibung auf dem Brief nur einen Name angeben, ohne komplette Anschrift und Absenderadresse. Wieso dann bei einer Email?!&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns also an wie ein Header aussieht, der die wichtigsten Angaben enthält:&lt;br /&gt;
&lt;br /&gt;
    $mailheader  = &amp;quot;From: PHP Email Tutorial&amp;lt;noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Reply-To: &amp;quot; .$name. &amp;quot;&amp;lt;&amp;quot; .$email. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Return-Path: noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;MIME-Version: 1.0\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Type: text/plain; charset=UTF-8\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Transfer-Encoding: 7bit\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Message-ID: &amp;lt;&amp;quot; .time(). &amp;quot; noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;X-Mailer: PHP v&amp;quot; .phpversion(). &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
Die Steuerungzeichen &amp;quot;\r\n&amp;quot; entsprechen einen Wagenrücklauf und Zeilenvorschub oder anders ausgedrückt, ein Zeilenumbruch. Diese Steuerungzeichen sind betriebssystemabhängig und müssen ggfs. angepasst werden. Auf Linux würde man z.B. nur &amp;quot;\n&amp;quot; verwenden. Schauen wir uns nun die anderen angaben an:&lt;br /&gt;
&lt;br /&gt;
    From - Das ist die Absendeadresse und der dazugehörige Name. Es ist üblich diesen in der Form Name anzugeben. Das ist die absolute Minimumangabe für inen Mailheader. Fehlt das From, wird der Versand der Mail fehlschlagen.&lt;br /&gt;
    Reply-To - Das Format kann entweder nur eine Email Adresse sein, oder man wählt das Format wir bei From. Dieses Feld ist die Antwortadresse an die die Mail geschickt wird, wenn wir im Mail Client auf antworten klicken.&lt;br /&gt;
    Return-Path - Konnte die Mail nicht zugestellt werden, wird dies an diese Adresse gemeldet.&lt;br /&gt;
    MIME-Version - Entspricht dem MIME Typ der Mail.&lt;br /&gt;
    Content-Type - Das ist die Information die dem Mail Client mitteilt, um welche Art Mail es sich handelt und welcher Zeichensatz zur Darstellung benutzt werden soll.&lt;br /&gt;
    Content-Transfer-Encoding - Dies beschreibt die Art der Übertragung und wie sowohl Mailserver, als auch Email Clients diese Mail interpretieren. 7bit ist die kleinste Form, die maximal mögliche Kompatibilität ermöglicht. Beim 7bit ASCII Zeichensatz können die ersten 128 zeichen der ASCII Tabelle dargestellt werden. Zeichen wie deutsche Umlaute sind darin nicht vorgesehen. Bei der 8bit Übertragung können bis zu 256 zeichen dargestellt werden. Ältere Mailerver, so liest man, verstehen nur 7bit und verwerfen Anfragen die mit 8bit übertragen werden sollen. Anders ausgedrückt, es kann passieren das die Mail nicht ankommt. Ich persönlich hatte damit allerdings noch nie Probleme und die 7bit &amp;quot;Zwangsangabe&amp;quot; scheint veraltet zu sein.&lt;br /&gt;
    Message-ID - Die Message ID ist einmalig, bzw. sollte es sein, wodurch die Mail eindeutig zugeordnet werden kann.&lt;br /&gt;
    X-Mailer - Beschreibt den Client der die Mail versendet hat. In unserem Fall geben wir die PHP Version an, damit Mailserver auf der Route wissen, dass diese Mail mit PHP verschickt wurde.&lt;br /&gt;
&lt;br /&gt;
Es gibt noch weitere Felder und Varianten, die uns aber im moment nicht kümmern. Im Abschnitt Mail mit Anhang werden wir noch einen etwas anderen Header kennen lernen.&lt;br /&gt;
Speziell die letzten beiden Angaben (Message ID und X_Mailer) im Header oben sind sehr wichtige Informationen. Fehlen diese Angaben, ist die Wahrscheinlichkeit sehr hoch, dass die Mail niemals beim Empfänger ankommen wird, weil die Mail irgendwo unterwegs in einem Spamfilter hängen bleibt und nicht weitergeleitet wird!&lt;br /&gt;
&lt;br /&gt;
Falls also eine Mail nicht ankommt, liegt das in den aller meisten Fällen entweder am Transfer-Encoding (7bit oder 8bit) oder an fehlenden Absendeangaben!&lt;br /&gt;
&lt;br /&gt;
Der Rest des Scripts ist sehr einfach, weil hier einfach nur noch die Mail verschickt wird.&lt;br /&gt;
&lt;br /&gt;
    if (@mail( $empfaenger, htmlspecialchars( $betreff ), $mailbody, $mailheader ))&lt;br /&gt;
    {&lt;br /&gt;
        // Bei erfolgreichem Versand Danke-Seite anzeigen&lt;br /&gt;
        echo &amp;#039;Danke, die Email wurde verschickt!&amp;#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Die mail-Funktion kennt noch einen 5. Parameter auf den ich jetzt nicht eingehen werde, weil dieser nur in den seltensten Fällen unterstützt wird. Wer mehr darüber erfahren möchte kann sich darüber in der Online-Doku informieren. Die mail-Funktion selbst liefert entweder TRUE oder FALSE zurück. Bei einem FALSE konnte die Mail nicht für den Versand übergeben werden und wir können entsprechend darauf reagieren. Im Falle von TRUE heisst das zwar das die Mail für den Versand angenommen wurde, aber es ist nicht prüfbar ob die Mail auch tatsächlich beim Empfänger ankam! Einige Gründe dafür stehen weiter oben. Wurde die Mail für den Versand akzeptiert, können wir darauf angemessen reagieren, indem wir den Besucher zu einer Danke-Seite weiterleiten oder, was weiter unter gezeigt wird, dem Benutzer eine Empfangsbestätigung, respektive Kopie der Mail an seine Adresse schicken.&lt;br /&gt;
&lt;br /&gt;
Soweit so gut. Dieser Abschnitt fiel etwas länger aus, weil ich die prinzipielle Funktionsweise und den Header beschrieben habe. Die nachfolgenden Beispiele sind über große Strecken identisch, deswegen spare ich mir dort die Erklärungen und gehe nur auf die abweichenden Passagen ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== E-Mail mit CSS Formatierung ===&lt;br /&gt;
&lt;br /&gt;
Eine Email im HTML Format zu senden ist im Grunde genommen nichts anderes, als eine einzelne Webseite per Email zu verschicken. Wir haben also mehr oder weniger freie Hand was die Gestaltung angeht, solange wir uns an die HTML und CSS Richtlinien halten. Das wird sofort ersichtlicht, wenn man das Template für die Email sieht.&lt;br /&gt;
&lt;br /&gt;
Listing der Datei mailbody.txt&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;quot; &amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html xmlns=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot; xml:lang=&amp;quot;de&amp;quot; lang=&amp;quot;de&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=utf-8&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Email als HTML&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt;&lt;br /&gt;
body { font: normal 12px Verdana, Arial, Helvetica, sans-serif; }&lt;br /&gt;
a { color: blue; text-decoration: none; }&lt;br /&gt;
h2 { font-size: 16px; font-weight: bold; }&lt;br /&gt;
.gruen { color: green; }&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;h2&amp;gt;Soeben ist eine Nachricht von &amp;lt;span class=&amp;quot;gruen&amp;quot;&amp;gt;###NAME###&amp;lt;/span&amp;gt; eingetroffen.&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Als Antwortadresse wurde &amp;lt;a href=&amp;quot;mailto:###EMAIL###&amp;quot;&amp;gt;###EMAIL###&amp;lt;/a&amp;gt; angegeben.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Die Nachricht die gesendet wurde lautet:&amp;lt;br /&amp;gt;&lt;br /&gt;
###NACHRICHT###&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Template besteht aus einer normalen HTML Datei mit etwas CSS. Auch hier treffen wir wieder unsere Platzhalter, die durch die Benutzereingaben ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
Die Datei funktionen.inc.php ist identisch mit wie beim vorherigen Beispiel. Auch die mail.php weicht nur minimal vom letzten Beispiel ab - das aber mit großer Wirkung!&lt;br /&gt;
Die erste Abweichung findet in der Zeile zum ersetzen des Platzhalters für die Nachricht statt.&lt;br /&gt;
&lt;br /&gt;
 $mailbody = str_replace( &amp;#039;###NACHRICHT###&amp;#039;, nl2br( htmlspecialchars( $nachricht ) ), $mailbody );&lt;br /&gt;
&lt;br /&gt;
Ergänzt wurde hier die Funktion nl2br. Diese Funktion bewirkt, dass das Steuerungzeichen für einen Zeilenumbruch (\n) in ein HTML-konformes Break (&amp;lt;br /&amp;gt;) umgewandelt wird. Ohne diese Funktion hätten wir bei der Ausgabe nur eine laaaange Zeile Text ohne neue Absätze und Umbrüche.&lt;br /&gt;
&lt;br /&gt;
Die nächsten beiden Veränderungen finden im Mail Header statt. Da wird nun ja keinen reinen Text, sondern HTML verschicken, muß natürlich der Content-Type angepasst werden. Ebenso ändern wir das Transfer-Encoding auf 8bit. Hier die beiden geänderten Zeilen:&lt;br /&gt;
&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Type: text/html; charset=UTF-8\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Transfer-Encoding: 8bit\r\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
That&amp;#039;s it!&lt;br /&gt;
Diese kleinen Veränderungen haben eine solch große Auswirkung auf die Art der Darstellung!&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis im Mail Client:&lt;br /&gt;
&lt;br /&gt;
(Deutlich zu sehen das die H2-Überschrift sich absetzt und auch der Name durch das CSS farblich hervorgehoben wird)&lt;br /&gt;
&lt;br /&gt;
Vermutlich stand jeder angehende Programmierer schon mal an dieser Stelle. Voller Stolz blickt man in sein Postfach, wo die erste Mail vom eigenen Formmailer eingetroffen ist. Dann denkt man sich: &amp;quot;Das war ja einfach, mit nur so wenigen Zeilen Code so ein Ergebnis zu erzielen. Wie schwer kann es da schon sein auch eine Datei mitzuschicken?!&amp;quot;.&lt;br /&gt;
Angesichts der oben gezeigten Beispiele, und wie minimal der Unterschied zwischen Text Mail und HTML Mail ist, neigt man dazu zu denken, dass dies mit einem Dateianhang ebenso einfach ist.&lt;br /&gt;
&lt;br /&gt;
Tja, leider ist dem nicht so. Das senden von Dateianhänge ist erheblich aufwändiger als das senden einer Text/HTML Mail. Das Formular ist abweichend, der Mail Header ist abweichend, der Mail Body muß in einzelne Teilbereiche getrennt werden, Dateianhänge müssen Richtlinien beachten, was die Zeilenlänge und die Art der Zeichen innerhalb der Mail angeht.&lt;br /&gt;
Glücklicherweise hilft uns PHP bei den meisten Sachen und deshalb werden wir auch dieses Problem meistern. :)&lt;br /&gt;
&lt;br /&gt;
=== E-Mail mit CSS und Anhang ===&lt;br /&gt;
Todo Quelle siehe oben (2012-03)&lt;br /&gt;
&lt;br /&gt;
HTML Email mit CSS Formatierung und Dateianhang&lt;br /&gt;
&lt;br /&gt;
Da wir eine Datei mit der Mail verschicken möchten, muß das Formular natürlich dahingehend erweitert werden, dass ein Upload auch möglich ist. In unserem Beispiel möchten wir eine JPG datei anhängen und erlauben auch nur das hochladen dieses Bildtyps.&lt;br /&gt;
Die Template Datei ist identisch zum vorherigen HTML Beispiel. In der Datei funktionen.inc.php fügen wir aber eine weitere Funktion hinzu, die für uns prüft, ob eine Datei hochgeladen wurde und ob es sich dabei um eine JPG Datei handelt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function checkFile()&lt;br /&gt;
{&lt;br /&gt;
    if ($_FILES[&amp;#039;datei&amp;#039;][&amp;#039;error&amp;#039;] == 0 &amp;amp;&amp;amp;&lt;br /&gt;
        $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;type&amp;#039;] == &amp;#039;image/jpeg&amp;#039;)&lt;br /&gt;
    {&lt;br /&gt;
        return $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;name&amp;#039;];&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        die( &amp;#039;Bitte eine gültige JPG Datei anhängen!&amp;#039; );&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der Datei mail.php wird sich nun einiges ändern. Zunächst erweitern wir die einleitende Abfrage dahingehend, dass wir feststellen ob auch eine Datei angehängt wurde ...&lt;br /&gt;
&lt;br /&gt;
 if (isset($_POST[&amp;#039;senden&amp;#039;]) &amp;amp;&amp;amp; $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;size&amp;#039;] &amp;gt; 0)&lt;br /&gt;
&lt;br /&gt;
... und fügen ebenso den Aufruf für die neue Funktion hinzu, die prüft ob ein JPG hochgeladen wurde:&lt;br /&gt;
&lt;br /&gt;
 $uploadname = checkFile();&lt;br /&gt;
&lt;br /&gt;
Das weitere Listing der Datei mail.php sieht wie folgt aus:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // Template mit dem Mailbody laden&lt;br /&gt;
    $template = file_get_contents( &amp;#039;mailbody.txt&amp;#039; );&lt;br /&gt;
    // Trenner für den Anhang&lt;br /&gt;
    $trenner = md5( time() );&lt;br /&gt;
 &lt;br /&gt;
    // Platzhalter mit den Benutzereingaben ersetzen&lt;br /&gt;
    $template = str_replace( &amp;#039;###NAME###&amp;#039;, htmlspecialchars( $name ), $template );&lt;br /&gt;
    $template = str_replace( &amp;#039;###EMAIL###&amp;#039;, $email, $template );&lt;br /&gt;
    $template = str_replace( &amp;#039;###NACHRICHT###&amp;#039;, nl2br( htmlspecialchars( $nachricht ) ), $template );&lt;br /&gt;
 &lt;br /&gt;
    // Mail Header erstellen&lt;br /&gt;
    $mailheader .= &amp;quot;Reply-To: &amp;quot; .$name. &amp;quot;&amp;lt;&amp;quot; .$email. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Return-Path: noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Message-ID: &amp;lt;&amp;quot; .time(). &amp;quot; noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;X-Mailer: PHP v&amp;quot; .phpversion(). &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;From: PHP Email Tutorial&amp;lt;noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;MIME-Version: 1.0\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Type: multipart/mixed;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot; boundary = &amp;quot; .$trenner;&lt;br /&gt;
    $mailheader .= &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    // Mailbody vorbereiten&lt;br /&gt;
    $mailbody  = &amp;quot;This is a multi-part message in MIME format\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;--&amp;quot; .$trenner. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Type: text/html; charset=UTF-8\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Transfer-Encoding: 8bit\r\n\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= $template. &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    // Anhang anfügen&lt;br /&gt;
    $mailbody .= &amp;quot;--&amp;quot; .$trenner. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Type: image/jpeg; name=\&amp;quot;&amp;quot; .$uploadname. &amp;quot;\&amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Transfer-Encoding: base64\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Disposition: attachment; filename=\&amp;quot;&amp;quot; .$uploadname. &amp;quot;\&amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= chunk_split( base64_encode( file_get_contents( $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;tmp_name&amp;#039;] ) ) );&lt;br /&gt;
    $mailbody .= &amp;quot;\n&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    // Email versenden&lt;br /&gt;
    if (@mail( $empfaenger, htmlspecialchars( $betreff ), $mailbody, $mailheader ))&lt;br /&gt;
    {&lt;br /&gt;
        // Bei erfolgreichem Versand Danke-Seite anzeigen&lt;br /&gt;
        echo &amp;#039;Danke, die Email wurde verschickt!&amp;#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen auf den ersten Blick, dass dieser Code ganz anders aussieht als das vorherige Beispiel. Gehen wir den Code mal der Reihe nach durch, um etwas Licht in&amp;#039;s Dunkel zu bringen.&lt;br /&gt;
&lt;br /&gt;
Im oberen Bereich erzeugen wir einen eindeutigen String, den wir zum trennen der verschiedenen Teilbereiche der Mail verwenden werden:&lt;br /&gt;
&lt;br /&gt;
 $trenner = md5( time() );&lt;br /&gt;
&lt;br /&gt;
Der erste Teil des Mail Header ist uns bereits bekannt, aber beim Content-Type benötigen wir nun eine andere Angabe.&lt;br /&gt;
&lt;br /&gt;
 $mailheader .= &amp;quot;Content-Type: multipart/mixed;\r\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
Dieser Content-Type ähnelt der Angabe &amp;quot;multipart/form-data&amp;quot; in einem HTML Formular, wenn wir dort ebenfalls gemischte Inhalte haben, nämlich Text und Dateien. Damit der Mail Client nun weiß an welchen Stellen im gesendeten Quellcode er Inhalte trennen muß, teilen wir im Header den boundary-String mit.&lt;br /&gt;
&lt;br /&gt;
An dieser Stelle möchte ich noch auf 2 wichtige Dinge hinweisen. Das Leerzeichen vor dem &amp;quot;boundary&amp;quot; im Header ist kein Versehen! Es kann tatsächlich dazu führen das eine Mail nicht korrekt dargestellt wird, wenn dieses Leerzeichen fehlt. Ebenso ist es wichtig, dass die &amp;quot;From&amp;quot;-Angabe unmittelbar vor der &amp;quot;MIME-Version&amp;quot; und dem &amp;quot;Content-Type&amp;quot; steht. Vertauscht man die Reihenfolge der Header Angabe, führt das z.B. bei mir dazu, dass ich im Thunderbird nur eine leere Seite als Mail angezeigt bekomme, obwohl der komplette Mail Inhalt im Quelltext einsehbar ist.&lt;br /&gt;
&lt;br /&gt;
Die nächste Zeile ...&lt;br /&gt;
&lt;br /&gt;
 $mailbody  = &amp;quot;This is a multi-part message in MIME format\r\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
... steht vor der Nachricht im Head Bereich in der Email. Sie scheint nicht zwingend erforderlich zu sein, aber Mail Clients fügen diese ebenfalls hinzu, wenn man mit z.B. Thunderbird eine Email verschickt. Ich vermute, dass dies aus Gründen der Kompatibilität zu einigen Mail Server geschieht.&lt;br /&gt;
&lt;br /&gt;
Nun folgt der erste Teil unserer Email, der Text.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    $mailbody .= &amp;quot;--&amp;quot; .$trenner. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Type: text/html; charset=UTF-8\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Transfer-Encoding: 8bit\r\n\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= $template. &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Durch den Trenner teilen wir dem Mail Client mit, dass zwischen diesem Trenner und dem nächsten Trenner, bzw. dem Ende der Mail, ein Teilabschnitt dieser Email steht. Damit der Client weiß um was es sich bei diesem Abschnitt handelt, teilen wir ihm das mithilfe des &amp;quot;Content-Type&amp;quot; und dem &amp;quot;Transfer-Encoding&amp;quot; mit. Durch die Angabe &amp;quot;text/html&amp;quot; weiß nun der Client, dass alles bis zum nächsten Trennen als HTML dargestellt werden soll.&lt;br /&gt;
&lt;br /&gt;
Der nächste Teilabschnitt der Mail ist unser Bild:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // Anhang anfügen&lt;br /&gt;
    $mailbody .= &amp;quot;--&amp;quot; .$trenner. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Type: image/jpeg; name=\&amp;quot;&amp;quot; .$uploadname. &amp;quot;\&amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Transfer-Encoding: base64\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Disposition: attachment; filename=\&amp;quot;&amp;quot; .$uploadname. &amp;quot;\&amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= chunk_split( base64_encode( file_get_contents( $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;tmp_name&amp;#039;] ) ) );&lt;br /&gt;
    $mailbody .= &amp;quot;\n&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wieder folgt zunächst der Trenner. Der Client stoppt seine HTML Ausgabe an dieser Position und wird ab diesem Punkt ausgeben, was ihm durch den &amp;quot;Content-Type&amp;quot; und das &amp;quot;Transfer-Encoding&amp;quot; aufgetragen wird. Wir sehen nun, dass wir als Content-Type eine JPG Datei ausgeben möchten. Der Name ergibt sich aus dem Rückgabewert der Funktion, die den Upload zuvor überprüft hat. Als Transfer-Encoding wird &amp;quot;base64&amp;quot; angegeben. Diese Angabe ist überaus wichtig um eine korrekte Übertragung der Daten zu gewährleisten. Mit der Angabe &amp;quot;Content-Disposition: attachment;&amp;quot; legen wir fest, dass der Anhang wirklich an die Mail angehängt wird. Eine andere Möglichkeit wäre hier das Einbetten in den Mailtext, indem man als Content-Disposition ein &amp;quot;inline&amp;quot; angibt. Die nächste Zeile ist ziemlich tricky:&lt;br /&gt;
&lt;br /&gt;
 $mailbody .= chunk_split( base64_encode( file_get_contents( $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;tmp_name&amp;#039;] ) ) );&lt;br /&gt;
&lt;br /&gt;
Arbeiten wir uns mal von Innen nach Außen durch, weil hier mehrere Funktionen verschachtelt sind. Mit file_get_contents wird eine Datei als String eingelesen. Dies ist hier möglich, weil diese Funktion seit PHP 4.3 binary safe ist. Als einzulesender Dateiname nehmen wir hier den Name der temporären datei, die durch den Upload auf dem Server gelandet ist. Diese Datei steht nur zu genau diesem Zeitpunkt zur Verfügung. Sobald das Script beendet wird oder eine andere Seite geladen wird, existiert diese Datei nicht mehr. Möchte man diese Datei erst zu einem späteren Zeitpunkt verarbeiten, muß man diese zunächst mit move_uploaded_file an eine andere Position kopieren.&lt;br /&gt;
Da wir nun die Bilddatei als String eingelesen haben, wird er mit base64_encode umgewandelt, damit die Datei beschädigt wird, falls es nicht möglich ist die Mail als 8bit zu übertragen. Es wird also aus Gründen der Kompatibilität gemacht. Anschließend wird der String mit chunk_split so aufbereitet, dass die Zeilenlänge 76 Zeichen nicht übersteigt.&lt;br /&gt;
&lt;br /&gt;
Das war&amp;#039;s! Die Daten können nun wieder mit der mail-Funktion versendet werden. Sollte man mehr als eine Datei anhängen wollen, kann man den letzten Schritt beliebig oft wiederholen. Erst Trenner setzen, dann Art der Daten und Übertragungsmodus angeben, die Datei anhängen, fertig.&lt;/div&gt;</summary>
		<author><name>178.7.132.100</name></author>
	</entry>
	<entry>
		<id>https://wiki.stephanschlegel.de/index.php?title=PHP_-_E-Mail_versenden&amp;diff=19051</id>
		<title>PHP - E-Mail versenden</title>
		<link rel="alternate" type="text/html" href="https://wiki.stephanschlegel.de/index.php?title=PHP_-_E-Mail_versenden&amp;diff=19051"/>
		<updated>2012-03-13T10:41:35Z</updated>

		<summary type="html">&lt;p&gt;178.7.132.100: /* E-Mail mit CSS und Anhang */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Links&lt;br /&gt;
&lt;br /&gt;
http://www.phpbuddy.eu/emails-mit-php-versenden.html?start=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Einfache Text E-Mail mit Template ===&lt;br /&gt;
Einfache Text Email&lt;br /&gt;
&lt;br /&gt;
Zuerst das Listing unserer Template Datei mailbody.txt&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Soeben ist eine Nachricht von ###NAME### eingetroffen.&lt;br /&gt;
Als Antwortadresse wurde ###EMAIL### angegeben.&lt;br /&gt;
Die Nachricht die gesendet wurde:&lt;br /&gt;
###NACHRICHT###&lt;br /&gt;
&lt;br /&gt;
Wie man unschwer erkennt, ist das ganz normaler und schlichter Text. Lediglich die Platzhalter darin fallen auf. Diese Platzhalter korrespondieren in unserem Script mit den Benutzereingaben und werden in unserem Script durch diese ersetzt.&lt;br /&gt;
Dadurch das wir den Text, der später per Email an uns geschickt wird, in einer eigenen Datei ablegen, können wir den Text schnell und flexibel beliebig verändern und erweitern. Da es sich hierbei um einen Mailer handelt der nur reinen Text verschickt, müssen wir auf jegliche Art von Formatierungen verzichten.&lt;br /&gt;
&lt;br /&gt;
Bisher haben wir das HTML-Formular, die Funktionen und das Mail Template kennengelernt, fehlt nur noch das Hauptscript, dass wir uns gleich mal vorknöpfen.&lt;br /&gt;
&lt;br /&gt;
Listing der Datei mail.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
 &lt;br /&gt;
header( &amp;#039;Content-Type: text/html; charset=utf-8&amp;#039; );&lt;br /&gt;
 &lt;br /&gt;
// Empfänger Email&lt;br /&gt;
$empfaenger = &amp;#039;max.mustermann@domain.tld&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
// Prüfen ob das Formular abgeschickt wurde&lt;br /&gt;
if (isset($_POST[&amp;#039;senden&amp;#039;]))&lt;br /&gt;
{&lt;br /&gt;
    // Funktionen einbinden&lt;br /&gt;
    include( &amp;#039;funktionen.inc.php&amp;#039; );&lt;br /&gt;
 &lt;br /&gt;
    // Benutzereingaben bereinigen und auf Injection prüfen&lt;br /&gt;
    cleanInput();&lt;br /&gt;
 &lt;br /&gt;
    // Name prüfen&lt;br /&gt;
    $name = checkName( $_POST[&amp;#039;name&amp;#039;] );&lt;br /&gt;
    // Email prüfen&lt;br /&gt;
    $email = checkEmail( $_POST[&amp;#039;email&amp;#039;] );&lt;br /&gt;
    // Betreff und Nachricht prüfen&lt;br /&gt;
    if ((strlen( $_POST[&amp;#039;betreff&amp;#039;] ) &amp;lt; 5) || (strlen( $_POST[&amp;#039;nachricht&amp;#039;] ) &amp;lt; 5))&lt;br /&gt;
    {&lt;br /&gt;
        die( &amp;#039;Bitte füllen Sie alle Felder aus!&amp;#039; );&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        $betreff   = $_POST[&amp;#039;betreff&amp;#039;];&lt;br /&gt;
        $nachricht = $_POST[&amp;#039;nachricht&amp;#039;];&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    // --------------------------------------------------------------------------------&lt;br /&gt;
    // Wurde das Script bisher nicht abgebrochen, wurde das Formular korrekt ausgefüllt&lt;br /&gt;
    // --------------------------------------------------------------------------------&lt;br /&gt;
 &lt;br /&gt;
    // Template mit dem Mailbody laden und für den Versand vorbereiten&lt;br /&gt;
    $mailbody = file_get_contents( &amp;#039;mailbody.txt&amp;#039; );&lt;br /&gt;
    // Platzhalter mit den Benutzereingaben ersetzen&lt;br /&gt;
    $mailbody = str_replace( &amp;#039;###NAME###&amp;#039;, htmlspecialchars( $name ), $mailbody );&lt;br /&gt;
    $mailbody = str_replace( &amp;#039;###EMAIL###&amp;#039;, $email, $mailbody );&lt;br /&gt;
    $mailbody = str_replace( &amp;#039;###NACHRICHT###&amp;#039;, htmlspecialchars( $nachricht ), $mailbody );&lt;br /&gt;
 &lt;br /&gt;
    // Mail Header erstellen&lt;br /&gt;
    $mailheader  = &amp;quot;From: PHP Email Tutorial&amp;lt;noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Reply-To: &amp;quot; .$name. &amp;quot;&amp;lt;&amp;quot; .$email. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Return-Path: noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;MIME-Version: 1.0\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Type: text/plain; charset=UTF-8\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Transfer-Encoding: 7bit\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Message-ID: &amp;lt;&amp;quot; .time(). &amp;quot; noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;X-Mailer: PHP v&amp;quot; .phpversion(). &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    // Email versenden&lt;br /&gt;
    if (@mail( $empfaenger, htmlspecialchars( $betreff ), $mailbody, $mailheader ))&lt;br /&gt;
    {&lt;br /&gt;
        // Bei erfolgreichem Versand Danke-Seite anzeigen&lt;br /&gt;
        echo &amp;#039;Danke, die Email wurde verschickt!&amp;#039;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das sieht im ersten Moment mehr und wilder aus, als es das eigentlich ist. Der obere Teil ist schnell erklärt. Zunächst setzen wir die Email des Empfängers, der idR wir selbst sind. Dann wird geprüft ob das Formular überhaupt abgeschickt wurde und wenn dem so ist, binden wir die benötigten Funktionen ein und überprüfen die Benutzereingaben.&lt;br /&gt;
&lt;br /&gt;
Mit den Zeilen ...&lt;br /&gt;
&lt;br /&gt;
    // Template mit dem Mailbody laden und für den Versand vorbereiten&lt;br /&gt;
    $mailbody = file_get_contents( &amp;#039;mailbody.txt&amp;#039; );&lt;br /&gt;
    // Platzhalter mit den Benutzereingaben ersetzen&lt;br /&gt;
    $mailbody = str_replace( &amp;#039;###NAME###&amp;#039;, htmlspecialchars( $name ), $mailbody );&lt;br /&gt;
    $mailbody = str_replace( &amp;#039;###EMAIL###&amp;#039;, $email, $mailbody );&lt;br /&gt;
    $mailbody = str_replace( &amp;#039;###NACHRICHT###&amp;#039;, htmlspecialchars( $nachricht ), $mailbody );&lt;br /&gt;
&lt;br /&gt;
... laden wir das Mail Template (file_get_contents) und ersetzen mit einfachen str_replace Funktionen die Platzhalter. Auch wenn wir bereits auf mögliche Injections geprüft haben, entschärfen wir dennoch die Eingaben mit htmlspecialchars, damit uns niemand etwas unterschiebt. Bei der Email ist das nicht nötig, da diese sonst nicht durch den Filter gekommen wäre.&lt;br /&gt;
&lt;br /&gt;
Jetzt kommen wir zu dem wichtigsten Teil, der ein erfolgreiches Versenden überhaupt erst möglich macht: dem Mail Header.&lt;br /&gt;
&lt;br /&gt;
Der Mail Header ist der Kopf der Email, der alle relevanten und wichtigen Informationen über unsere Email enthält. Sehr sehr häufig sieht man in Scripts und Tutorials, dass hier lediglich das &amp;quot;From:&amp;quot; angegeben ist. Wenn nur diese Information angegeben ist, bleibt die Mail sehr häufig in einem Spamfilter hängen. Kein Mensch würde auf die Idee kommen einen echten Brief zu verschicken und als Beschreibung auf dem Brief nur einen Name angeben, ohne komplette Anschrift und Absenderadresse. Wieso dann bei einer Email?!&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns also an wie ein Header aussieht, der die wichtigsten Angaben enthält:&lt;br /&gt;
&lt;br /&gt;
    $mailheader  = &amp;quot;From: PHP Email Tutorial&amp;lt;noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Reply-To: &amp;quot; .$name. &amp;quot;&amp;lt;&amp;quot; .$email. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Return-Path: noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;MIME-Version: 1.0\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Type: text/plain; charset=UTF-8\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Transfer-Encoding: 7bit\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Message-ID: &amp;lt;&amp;quot; .time(). &amp;quot; noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;X-Mailer: PHP v&amp;quot; .phpversion(). &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
Die Steuerungzeichen &amp;quot;\r\n&amp;quot; entsprechen einen Wagenrücklauf und Zeilenvorschub oder anders ausgedrückt, ein Zeilenumbruch. Diese Steuerungzeichen sind betriebssystemabhängig und müssen ggfs. angepasst werden. Auf Linux würde man z.B. nur &amp;quot;\n&amp;quot; verwenden. Schauen wir uns nun die anderen angaben an:&lt;br /&gt;
&lt;br /&gt;
    From - Das ist die Absendeadresse und der dazugehörige Name. Es ist üblich diesen in der Form Name anzugeben. Das ist die absolute Minimumangabe für inen Mailheader. Fehlt das From, wird der Versand der Mail fehlschlagen.&lt;br /&gt;
    Reply-To - Das Format kann entweder nur eine Email Adresse sein, oder man wählt das Format wir bei From. Dieses Feld ist die Antwortadresse an die die Mail geschickt wird, wenn wir im Mail Client auf antworten klicken.&lt;br /&gt;
    Return-Path - Konnte die Mail nicht zugestellt werden, wird dies an diese Adresse gemeldet.&lt;br /&gt;
    MIME-Version - Entspricht dem MIME Typ der Mail.&lt;br /&gt;
    Content-Type - Das ist die Information die dem Mail Client mitteilt, um welche Art Mail es sich handelt und welcher Zeichensatz zur Darstellung benutzt werden soll.&lt;br /&gt;
    Content-Transfer-Encoding - Dies beschreibt die Art der Übertragung und wie sowohl Mailserver, als auch Email Clients diese Mail interpretieren. 7bit ist die kleinste Form, die maximal mögliche Kompatibilität ermöglicht. Beim 7bit ASCII Zeichensatz können die ersten 128 zeichen der ASCII Tabelle dargestellt werden. Zeichen wie deutsche Umlaute sind darin nicht vorgesehen. Bei der 8bit Übertragung können bis zu 256 zeichen dargestellt werden. Ältere Mailerver, so liest man, verstehen nur 7bit und verwerfen Anfragen die mit 8bit übertragen werden sollen. Anders ausgedrückt, es kann passieren das die Mail nicht ankommt. Ich persönlich hatte damit allerdings noch nie Probleme und die 7bit &amp;quot;Zwangsangabe&amp;quot; scheint veraltet zu sein.&lt;br /&gt;
    Message-ID - Die Message ID ist einmalig, bzw. sollte es sein, wodurch die Mail eindeutig zugeordnet werden kann.&lt;br /&gt;
    X-Mailer - Beschreibt den Client der die Mail versendet hat. In unserem Fall geben wir die PHP Version an, damit Mailserver auf der Route wissen, dass diese Mail mit PHP verschickt wurde.&lt;br /&gt;
&lt;br /&gt;
Es gibt noch weitere Felder und Varianten, die uns aber im moment nicht kümmern. Im Abschnitt Mail mit Anhang werden wir noch einen etwas anderen Header kennen lernen.&lt;br /&gt;
Speziell die letzten beiden Angaben (Message ID und X_Mailer) im Header oben sind sehr wichtige Informationen. Fehlen diese Angaben, ist die Wahrscheinlichkeit sehr hoch, dass die Mail niemals beim Empfänger ankommen wird, weil die Mail irgendwo unterwegs in einem Spamfilter hängen bleibt und nicht weitergeleitet wird!&lt;br /&gt;
&lt;br /&gt;
Falls also eine Mail nicht ankommt, liegt das in den aller meisten Fällen entweder am Transfer-Encoding (7bit oder 8bit) oder an fehlenden Absendeangaben!&lt;br /&gt;
&lt;br /&gt;
Der Rest des Scripts ist sehr einfach, weil hier einfach nur noch die Mail verschickt wird.&lt;br /&gt;
&lt;br /&gt;
    if (@mail( $empfaenger, htmlspecialchars( $betreff ), $mailbody, $mailheader ))&lt;br /&gt;
    {&lt;br /&gt;
        // Bei erfolgreichem Versand Danke-Seite anzeigen&lt;br /&gt;
        echo &amp;#039;Danke, die Email wurde verschickt!&amp;#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Die mail-Funktion kennt noch einen 5. Parameter auf den ich jetzt nicht eingehen werde, weil dieser nur in den seltensten Fällen unterstützt wird. Wer mehr darüber erfahren möchte kann sich darüber in der Online-Doku informieren. Die mail-Funktion selbst liefert entweder TRUE oder FALSE zurück. Bei einem FALSE konnte die Mail nicht für den Versand übergeben werden und wir können entsprechend darauf reagieren. Im Falle von TRUE heisst das zwar das die Mail für den Versand angenommen wurde, aber es ist nicht prüfbar ob die Mail auch tatsächlich beim Empfänger ankam! Einige Gründe dafür stehen weiter oben. Wurde die Mail für den Versand akzeptiert, können wir darauf angemessen reagieren, indem wir den Besucher zu einer Danke-Seite weiterleiten oder, was weiter unter gezeigt wird, dem Benutzer eine Empfangsbestätigung, respektive Kopie der Mail an seine Adresse schicken.&lt;br /&gt;
&lt;br /&gt;
Soweit so gut. Dieser Abschnitt fiel etwas länger aus, weil ich die prinzipielle Funktionsweise und den Header beschrieben habe. Die nachfolgenden Beispiele sind über große Strecken identisch, deswegen spare ich mir dort die Erklärungen und gehe nur auf die abweichenden Passagen ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== E-Mail mit CSS Formatierung ===&lt;br /&gt;
HTML Email mit CSS Formatierung&lt;br /&gt;
&lt;br /&gt;
Eine Email im HTML Format zu senden ist im Grunde genommen nichts anderes, als eine einzelne Webseite per Email zu verschicken. Wir haben also mehr oder weniger freie Hand was die Gestaltung angeht, solange wir uns an die HTML und CSS Richtlinien halten. Das wird sofort ersichtlicht, wenn man das Template für die Email sieht.&lt;br /&gt;
&lt;br /&gt;
Listing der Datei mailbody.txt&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;quot; &amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html xmlns=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot; xml:lang=&amp;quot;de&amp;quot; lang=&amp;quot;de&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=utf-8&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Email als HTML&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt;&lt;br /&gt;
body { font: normal 12px Verdana, Arial, Helvetica, sans-serif; }&lt;br /&gt;
a { color: blue; text-decoration: none; }&lt;br /&gt;
h2 { font-size: 16px; font-weight: bold; }&lt;br /&gt;
.gruen { color: green; }&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;h2&amp;gt;Soeben ist eine Nachricht von &amp;lt;span class=&amp;quot;gruen&amp;quot;&amp;gt;###NAME###&amp;lt;/span&amp;gt; eingetroffen.&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Als Antwortadresse wurde &amp;lt;a href=&amp;quot;mailto:###EMAIL###&amp;quot;&amp;gt;###EMAIL###&amp;lt;/a&amp;gt; angegeben.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Die Nachricht die gesendet wurde lautet:&amp;lt;br /&amp;gt;&lt;br /&gt;
###NACHRICHT###&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Template besteht aus einer normalen HTML Datei mit etwas CSS. Auch hier treffen wir wieder unsere Platzhalter, die durch die Benutzereingaben ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
Die Datei funktionen.inc.php ist identisch mit wie beim vorherigen Beispiel. Auch die mail.php weicht nur minimal vom letzten Beispiel ab - das aber mit großer Wirkung!&lt;br /&gt;
Die erste Abweichung findet in der Zeile zum ersetzen des Platzhalters für die Nachricht statt.&lt;br /&gt;
&lt;br /&gt;
$mailbody = str_replace( &amp;#039;###NACHRICHT###&amp;#039;, nl2br( htmlspecialchars( $nachricht ) ), $mailbody );&lt;br /&gt;
&lt;br /&gt;
Ergänzt wurde hier die Funktion nl2br. Diese Funktion bewirkt, dass das Steuerungzeichen für einen Zeilenumbruch (\n) in ein HTML-konformes Break (&amp;lt;br /&amp;gt;) umgewandelt wird. Ohne diese Funktion hätten wir bei der Ausgabe nur eine laaaange Zeile Text ohne neue Absätze und Umbrüche.&lt;br /&gt;
&lt;br /&gt;
Die nächsten beiden Veränderungen finden im Mail Header statt. Da wird nun ja keinen reinen Text, sondern HTML verschicken, muß natürlich der Content-Type angepasst werden. Ebenso ändern wir das Transfer-Encoding auf 8bit. Hier die beiden geänderten Zeilen:&lt;br /&gt;
&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Type: text/html; charset=UTF-8\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Transfer-Encoding: 8bit\r\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
That&amp;#039;s it!&lt;br /&gt;
Diese kleinen Veränderungen haben eine solch große Auswirkung auf die Art der Darstellung!&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis im Mail Client:&lt;br /&gt;
&lt;br /&gt;
(Deutlich zu sehen das die H2-Überschrift sich absetzt und auch der Name durch das CSS farblich hervorgehoben wird)&lt;br /&gt;
&lt;br /&gt;
Vermutlich stand jeder angehende Programmierer schon mal an dieser Stelle. Voller Stolz blickt man in sein Postfach, wo die erste Mail vom eigenen Formmailer eingetroffen ist. Dann denkt man sich: &amp;quot;Das war ja einfach, mit nur so wenigen Zeilen Code so ein Ergebnis zu erzielen. Wie schwer kann es da schon sein auch eine Datei mitzuschicken?!&amp;quot;.&lt;br /&gt;
Angesichts der oben gezeigten Beispiele, und wie minimal der Unterschied zwischen Text Mail und HTML Mail ist, neigt man dazu zu denken, dass dies mit einem Dateianhang ebenso einfach ist.&lt;br /&gt;
&lt;br /&gt;
Tja, leider ist dem nicht so. Das senden von Dateianhänge ist erheblich aufwändiger als das senden einer Text/HTML Mail. Das Formular ist abweichend, der Mail Header ist abweichend, der Mail Body muß in einzelne Teilbereiche getrennt werden, Dateianhänge müssen Richtlinien beachten, was die Zeilenlänge und die Art der Zeichen innerhalb der Mail angeht.&lt;br /&gt;
Glücklicherweise hilft uns PHP bei den meisten Sachen und deshalb werden wir auch dieses Problem meistern. :)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== E-Mail mit CSS und Anhang ===&lt;br /&gt;
Todo Quelle siehe oben (2012-03)&lt;br /&gt;
&lt;br /&gt;
HTML Email mit CSS Formatierung und Dateianhang&lt;br /&gt;
&lt;br /&gt;
Da wir eine Datei mit der Mail verschicken möchten, muß das Formular natürlich dahingehend erweitert werden, dass ein Upload auch möglich ist. In unserem Beispiel möchten wir eine JPG datei anhängen und erlauben auch nur das hochladen dieses Bildtyps.&lt;br /&gt;
Die Template Datei ist identisch zum vorherigen HTML Beispiel. In der Datei funktionen.inc.php fügen wir aber eine weitere Funktion hinzu, die für uns prüft, ob eine Datei hochgeladen wurde und ob es sich dabei um eine JPG Datei handelt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function checkFile()&lt;br /&gt;
{&lt;br /&gt;
    if ($_FILES[&amp;#039;datei&amp;#039;][&amp;#039;error&amp;#039;] == 0 &amp;amp;&amp;amp;&lt;br /&gt;
        $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;type&amp;#039;] == &amp;#039;image/jpeg&amp;#039;)&lt;br /&gt;
    {&lt;br /&gt;
        return $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;name&amp;#039;];&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        die( &amp;#039;Bitte eine gültige JPG Datei anhängen!&amp;#039; );&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der Datei mail.php wird sich nun einiges ändern. Zunächst erweitern wir die einleitende Abfrage dahingehend, dass wir feststellen ob auch eine Datei angehängt wurde ...&lt;br /&gt;
&lt;br /&gt;
 if (isset($_POST[&amp;#039;senden&amp;#039;]) &amp;amp;&amp;amp; $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;size&amp;#039;] &amp;gt; 0)&lt;br /&gt;
&lt;br /&gt;
... und fügen ebenso den Aufruf für die neue Funktion hinzu, die prüft ob ein JPG hochgeladen wurde:&lt;br /&gt;
&lt;br /&gt;
 $uploadname = checkFile();&lt;br /&gt;
&lt;br /&gt;
Das weitere Listing der Datei mail.php sieht wie folgt aus:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // Template mit dem Mailbody laden&lt;br /&gt;
    $template = file_get_contents( &amp;#039;mailbody.txt&amp;#039; );&lt;br /&gt;
    // Trenner für den Anhang&lt;br /&gt;
    $trenner = md5( time() );&lt;br /&gt;
 &lt;br /&gt;
    // Platzhalter mit den Benutzereingaben ersetzen&lt;br /&gt;
    $template = str_replace( &amp;#039;###NAME###&amp;#039;, htmlspecialchars( $name ), $template );&lt;br /&gt;
    $template = str_replace( &amp;#039;###EMAIL###&amp;#039;, $email, $template );&lt;br /&gt;
    $template = str_replace( &amp;#039;###NACHRICHT###&amp;#039;, nl2br( htmlspecialchars( $nachricht ) ), $template );&lt;br /&gt;
 &lt;br /&gt;
    // Mail Header erstellen&lt;br /&gt;
    $mailheader .= &amp;quot;Reply-To: &amp;quot; .$name. &amp;quot;&amp;lt;&amp;quot; .$email. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Return-Path: noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Message-ID: &amp;lt;&amp;quot; .time(). &amp;quot; noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;X-Mailer: PHP v&amp;quot; .phpversion(). &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;From: PHP Email Tutorial&amp;lt;noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;MIME-Version: 1.0\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Type: multipart/mixed;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot; boundary = &amp;quot; .$trenner;&lt;br /&gt;
    $mailheader .= &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    // Mailbody vorbereiten&lt;br /&gt;
    $mailbody  = &amp;quot;This is a multi-part message in MIME format\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;--&amp;quot; .$trenner. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Type: text/html; charset=UTF-8\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Transfer-Encoding: 8bit\r\n\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= $template. &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    // Anhang anfügen&lt;br /&gt;
    $mailbody .= &amp;quot;--&amp;quot; .$trenner. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Type: image/jpeg; name=\&amp;quot;&amp;quot; .$uploadname. &amp;quot;\&amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Transfer-Encoding: base64\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Disposition: attachment; filename=\&amp;quot;&amp;quot; .$uploadname. &amp;quot;\&amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= chunk_split( base64_encode( file_get_contents( $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;tmp_name&amp;#039;] ) ) );&lt;br /&gt;
    $mailbody .= &amp;quot;\n&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    // Email versenden&lt;br /&gt;
    if (@mail( $empfaenger, htmlspecialchars( $betreff ), $mailbody, $mailheader ))&lt;br /&gt;
    {&lt;br /&gt;
        // Bei erfolgreichem Versand Danke-Seite anzeigen&lt;br /&gt;
        echo &amp;#039;Danke, die Email wurde verschickt!&amp;#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen auf den ersten Blick, dass dieser Code ganz anders aussieht als das vorherige Beispiel. Gehen wir den Code mal der Reihe nach durch, um etwas Licht in&amp;#039;s Dunkel zu bringen.&lt;br /&gt;
&lt;br /&gt;
Im oberen Bereich erzeugen wir einen eindeutigen String, den wir zum trennen der verschiedenen Teilbereiche der Mail verwenden werden:&lt;br /&gt;
&lt;br /&gt;
 $trenner = md5( time() );&lt;br /&gt;
&lt;br /&gt;
Der erste Teil des Mail Header ist uns bereits bekannt, aber beim Content-Type benötigen wir nun eine andere Angabe.&lt;br /&gt;
&lt;br /&gt;
 $mailheader .= &amp;quot;Content-Type: multipart/mixed;\r\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
Dieser Content-Type ähnelt der Angabe &amp;quot;multipart/form-data&amp;quot; in einem HTML Formular, wenn wir dort ebenfalls gemischte Inhalte haben, nämlich Text und Dateien. Damit der Mail Client nun weiß an welchen Stellen im gesendeten Quellcode er Inhalte trennen muß, teilen wir im Header den boundary-String mit.&lt;br /&gt;
&lt;br /&gt;
An dieser Stelle möchte ich noch auf 2 wichtige Dinge hinweisen. Das Leerzeichen vor dem &amp;quot;boundary&amp;quot; im Header ist kein Versehen! Es kann tatsächlich dazu führen das eine Mail nicht korrekt dargestellt wird, wenn dieses Leerzeichen fehlt. Ebenso ist es wichtig, dass die &amp;quot;From&amp;quot;-Angabe unmittelbar vor der &amp;quot;MIME-Version&amp;quot; und dem &amp;quot;Content-Type&amp;quot; steht. Vertauscht man die Reihenfolge der Header Angabe, führt das z.B. bei mir dazu, dass ich im Thunderbird nur eine leere Seite als Mail angezeigt bekomme, obwohl der komplette Mail Inhalt im Quelltext einsehbar ist.&lt;br /&gt;
&lt;br /&gt;
Die nächste Zeile ...&lt;br /&gt;
&lt;br /&gt;
 $mailbody  = &amp;quot;This is a multi-part message in MIME format\r\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
... steht vor der Nachricht im Head Bereich in der Email. Sie scheint nicht zwingend erforderlich zu sein, aber Mail Clients fügen diese ebenfalls hinzu, wenn man mit z.B. Thunderbird eine Email verschickt. Ich vermute, dass dies aus Gründen der Kompatibilität zu einigen Mail Server geschieht.&lt;br /&gt;
&lt;br /&gt;
Nun folgt der erste Teil unserer Email, der Text.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    $mailbody .= &amp;quot;--&amp;quot; .$trenner. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Type: text/html; charset=UTF-8\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Transfer-Encoding: 8bit\r\n\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= $template. &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Durch den Trenner teilen wir dem Mail Client mit, dass zwischen diesem Trenner und dem nächsten Trenner, bzw. dem Ende der Mail, ein Teilabschnitt dieser Email steht. Damit der Client weiß um was es sich bei diesem Abschnitt handelt, teilen wir ihm das mithilfe des &amp;quot;Content-Type&amp;quot; und dem &amp;quot;Transfer-Encoding&amp;quot; mit. Durch die Angabe &amp;quot;text/html&amp;quot; weiß nun der Client, dass alles bis zum nächsten Trennen als HTML dargestellt werden soll.&lt;br /&gt;
&lt;br /&gt;
Der nächste Teilabschnitt der Mail ist unser Bild:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // Anhang anfügen&lt;br /&gt;
    $mailbody .= &amp;quot;--&amp;quot; .$trenner. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Type: image/jpeg; name=\&amp;quot;&amp;quot; .$uploadname. &amp;quot;\&amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Transfer-Encoding: base64\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Disposition: attachment; filename=\&amp;quot;&amp;quot; .$uploadname. &amp;quot;\&amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= chunk_split( base64_encode( file_get_contents( $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;tmp_name&amp;#039;] ) ) );&lt;br /&gt;
    $mailbody .= &amp;quot;\n&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wieder folgt zunächst der Trenner. Der Client stoppt seine HTML Ausgabe an dieser Position und wird ab diesem Punkt ausgeben, was ihm durch den &amp;quot;Content-Type&amp;quot; und das &amp;quot;Transfer-Encoding&amp;quot; aufgetragen wird. Wir sehen nun, dass wir als Content-Type eine JPG Datei ausgeben möchten. Der Name ergibt sich aus dem Rückgabewert der Funktion, die den Upload zuvor überprüft hat. Als Transfer-Encoding wird &amp;quot;base64&amp;quot; angegeben. Diese Angabe ist überaus wichtig um eine korrekte Übertragung der Daten zu gewährleisten. Mit der Angabe &amp;quot;Content-Disposition: attachment;&amp;quot; legen wir fest, dass der Anhang wirklich an die Mail angehängt wird. Eine andere Möglichkeit wäre hier das Einbetten in den Mailtext, indem man als Content-Disposition ein &amp;quot;inline&amp;quot; angibt. Die nächste Zeile ist ziemlich tricky:&lt;br /&gt;
&lt;br /&gt;
 $mailbody .= chunk_split( base64_encode( file_get_contents( $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;tmp_name&amp;#039;] ) ) );&lt;br /&gt;
&lt;br /&gt;
Arbeiten wir uns mal von Innen nach Außen durch, weil hier mehrere Funktionen verschachtelt sind. Mit file_get_contents wird eine Datei als String eingelesen. Dies ist hier möglich, weil diese Funktion seit PHP 4.3 binary safe ist. Als einzulesender Dateiname nehmen wir hier den Name der temporären datei, die durch den Upload auf dem Server gelandet ist. Diese Datei steht nur zu genau diesem Zeitpunkt zur Verfügung. Sobald das Script beendet wird oder eine andere Seite geladen wird, existiert diese Datei nicht mehr. Möchte man diese Datei erst zu einem späteren Zeitpunkt verarbeiten, muß man diese zunächst mit move_uploaded_file an eine andere Position kopieren.&lt;br /&gt;
Da wir nun die Bilddatei als String eingelesen haben, wird er mit base64_encode umgewandelt, damit die Datei beschädigt wird, falls es nicht möglich ist die Mail als 8bit zu übertragen. Es wird also aus Gründen der Kompatibilität gemacht. Anschließend wird der String mit chunk_split so aufbereitet, dass die Zeilenlänge 76 Zeichen nicht übersteigt.&lt;br /&gt;
&lt;br /&gt;
Das war&amp;#039;s! Die Daten können nun wieder mit der mail-Funktion versendet werden. Sollte man mehr als eine Datei anhängen wollen, kann man den letzten Schritt beliebig oft wiederholen. Erst Trenner setzen, dann Art der Daten und Übertragungsmodus angeben, die Datei anhängen, fertig.&lt;/div&gt;</summary>
		<author><name>178.7.132.100</name></author>
	</entry>
	<entry>
		<id>https://wiki.stephanschlegel.de/index.php?title=PHP_-_E-Mail_versenden&amp;diff=19050</id>
		<title>PHP - E-Mail versenden</title>
		<link rel="alternate" type="text/html" href="https://wiki.stephanschlegel.de/index.php?title=PHP_-_E-Mail_versenden&amp;diff=19050"/>
		<updated>2012-03-13T10:40:47Z</updated>

		<summary type="html">&lt;p&gt;178.7.132.100: /* E-Mail mit CSS und Anhang */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Links&lt;br /&gt;
&lt;br /&gt;
http://www.phpbuddy.eu/emails-mit-php-versenden.html?start=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Einfache Text E-Mail mit Template ===&lt;br /&gt;
Einfache Text Email&lt;br /&gt;
&lt;br /&gt;
Zuerst das Listing unserer Template Datei mailbody.txt&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Soeben ist eine Nachricht von ###NAME### eingetroffen.&lt;br /&gt;
Als Antwortadresse wurde ###EMAIL### angegeben.&lt;br /&gt;
Die Nachricht die gesendet wurde:&lt;br /&gt;
###NACHRICHT###&lt;br /&gt;
&lt;br /&gt;
Wie man unschwer erkennt, ist das ganz normaler und schlichter Text. Lediglich die Platzhalter darin fallen auf. Diese Platzhalter korrespondieren in unserem Script mit den Benutzereingaben und werden in unserem Script durch diese ersetzt.&lt;br /&gt;
Dadurch das wir den Text, der später per Email an uns geschickt wird, in einer eigenen Datei ablegen, können wir den Text schnell und flexibel beliebig verändern und erweitern. Da es sich hierbei um einen Mailer handelt der nur reinen Text verschickt, müssen wir auf jegliche Art von Formatierungen verzichten.&lt;br /&gt;
&lt;br /&gt;
Bisher haben wir das HTML-Formular, die Funktionen und das Mail Template kennengelernt, fehlt nur noch das Hauptscript, dass wir uns gleich mal vorknöpfen.&lt;br /&gt;
&lt;br /&gt;
Listing der Datei mail.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
 &lt;br /&gt;
header( &amp;#039;Content-Type: text/html; charset=utf-8&amp;#039; );&lt;br /&gt;
 &lt;br /&gt;
// Empfänger Email&lt;br /&gt;
$empfaenger = &amp;#039;max.mustermann@domain.tld&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
// Prüfen ob das Formular abgeschickt wurde&lt;br /&gt;
if (isset($_POST[&amp;#039;senden&amp;#039;]))&lt;br /&gt;
{&lt;br /&gt;
    // Funktionen einbinden&lt;br /&gt;
    include( &amp;#039;funktionen.inc.php&amp;#039; );&lt;br /&gt;
 &lt;br /&gt;
    // Benutzereingaben bereinigen und auf Injection prüfen&lt;br /&gt;
    cleanInput();&lt;br /&gt;
 &lt;br /&gt;
    // Name prüfen&lt;br /&gt;
    $name = checkName( $_POST[&amp;#039;name&amp;#039;] );&lt;br /&gt;
    // Email prüfen&lt;br /&gt;
    $email = checkEmail( $_POST[&amp;#039;email&amp;#039;] );&lt;br /&gt;
    // Betreff und Nachricht prüfen&lt;br /&gt;
    if ((strlen( $_POST[&amp;#039;betreff&amp;#039;] ) &amp;lt; 5) || (strlen( $_POST[&amp;#039;nachricht&amp;#039;] ) &amp;lt; 5))&lt;br /&gt;
    {&lt;br /&gt;
        die( &amp;#039;Bitte füllen Sie alle Felder aus!&amp;#039; );&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        $betreff   = $_POST[&amp;#039;betreff&amp;#039;];&lt;br /&gt;
        $nachricht = $_POST[&amp;#039;nachricht&amp;#039;];&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    // --------------------------------------------------------------------------------&lt;br /&gt;
    // Wurde das Script bisher nicht abgebrochen, wurde das Formular korrekt ausgefüllt&lt;br /&gt;
    // --------------------------------------------------------------------------------&lt;br /&gt;
 &lt;br /&gt;
    // Template mit dem Mailbody laden und für den Versand vorbereiten&lt;br /&gt;
    $mailbody = file_get_contents( &amp;#039;mailbody.txt&amp;#039; );&lt;br /&gt;
    // Platzhalter mit den Benutzereingaben ersetzen&lt;br /&gt;
    $mailbody = str_replace( &amp;#039;###NAME###&amp;#039;, htmlspecialchars( $name ), $mailbody );&lt;br /&gt;
    $mailbody = str_replace( &amp;#039;###EMAIL###&amp;#039;, $email, $mailbody );&lt;br /&gt;
    $mailbody = str_replace( &amp;#039;###NACHRICHT###&amp;#039;, htmlspecialchars( $nachricht ), $mailbody );&lt;br /&gt;
 &lt;br /&gt;
    // Mail Header erstellen&lt;br /&gt;
    $mailheader  = &amp;quot;From: PHP Email Tutorial&amp;lt;noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Reply-To: &amp;quot; .$name. &amp;quot;&amp;lt;&amp;quot; .$email. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Return-Path: noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;MIME-Version: 1.0\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Type: text/plain; charset=UTF-8\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Transfer-Encoding: 7bit\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Message-ID: &amp;lt;&amp;quot; .time(). &amp;quot; noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;X-Mailer: PHP v&amp;quot; .phpversion(). &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    // Email versenden&lt;br /&gt;
    if (@mail( $empfaenger, htmlspecialchars( $betreff ), $mailbody, $mailheader ))&lt;br /&gt;
    {&lt;br /&gt;
        // Bei erfolgreichem Versand Danke-Seite anzeigen&lt;br /&gt;
        echo &amp;#039;Danke, die Email wurde verschickt!&amp;#039;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das sieht im ersten Moment mehr und wilder aus, als es das eigentlich ist. Der obere Teil ist schnell erklärt. Zunächst setzen wir die Email des Empfängers, der idR wir selbst sind. Dann wird geprüft ob das Formular überhaupt abgeschickt wurde und wenn dem so ist, binden wir die benötigten Funktionen ein und überprüfen die Benutzereingaben.&lt;br /&gt;
&lt;br /&gt;
Mit den Zeilen ...&lt;br /&gt;
&lt;br /&gt;
    // Template mit dem Mailbody laden und für den Versand vorbereiten&lt;br /&gt;
    $mailbody = file_get_contents( &amp;#039;mailbody.txt&amp;#039; );&lt;br /&gt;
    // Platzhalter mit den Benutzereingaben ersetzen&lt;br /&gt;
    $mailbody = str_replace( &amp;#039;###NAME###&amp;#039;, htmlspecialchars( $name ), $mailbody );&lt;br /&gt;
    $mailbody = str_replace( &amp;#039;###EMAIL###&amp;#039;, $email, $mailbody );&lt;br /&gt;
    $mailbody = str_replace( &amp;#039;###NACHRICHT###&amp;#039;, htmlspecialchars( $nachricht ), $mailbody );&lt;br /&gt;
&lt;br /&gt;
... laden wir das Mail Template (file_get_contents) und ersetzen mit einfachen str_replace Funktionen die Platzhalter. Auch wenn wir bereits auf mögliche Injections geprüft haben, entschärfen wir dennoch die Eingaben mit htmlspecialchars, damit uns niemand etwas unterschiebt. Bei der Email ist das nicht nötig, da diese sonst nicht durch den Filter gekommen wäre.&lt;br /&gt;
&lt;br /&gt;
Jetzt kommen wir zu dem wichtigsten Teil, der ein erfolgreiches Versenden überhaupt erst möglich macht: dem Mail Header.&lt;br /&gt;
&lt;br /&gt;
Der Mail Header ist der Kopf der Email, der alle relevanten und wichtigen Informationen über unsere Email enthält. Sehr sehr häufig sieht man in Scripts und Tutorials, dass hier lediglich das &amp;quot;From:&amp;quot; angegeben ist. Wenn nur diese Information angegeben ist, bleibt die Mail sehr häufig in einem Spamfilter hängen. Kein Mensch würde auf die Idee kommen einen echten Brief zu verschicken und als Beschreibung auf dem Brief nur einen Name angeben, ohne komplette Anschrift und Absenderadresse. Wieso dann bei einer Email?!&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns also an wie ein Header aussieht, der die wichtigsten Angaben enthält:&lt;br /&gt;
&lt;br /&gt;
    $mailheader  = &amp;quot;From: PHP Email Tutorial&amp;lt;noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Reply-To: &amp;quot; .$name. &amp;quot;&amp;lt;&amp;quot; .$email. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Return-Path: noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;MIME-Version: 1.0\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Type: text/plain; charset=UTF-8\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Transfer-Encoding: 7bit\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Message-ID: &amp;lt;&amp;quot; .time(). &amp;quot; noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;X-Mailer: PHP v&amp;quot; .phpversion(). &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
Die Steuerungzeichen &amp;quot;\r\n&amp;quot; entsprechen einen Wagenrücklauf und Zeilenvorschub oder anders ausgedrückt, ein Zeilenumbruch. Diese Steuerungzeichen sind betriebssystemabhängig und müssen ggfs. angepasst werden. Auf Linux würde man z.B. nur &amp;quot;\n&amp;quot; verwenden. Schauen wir uns nun die anderen angaben an:&lt;br /&gt;
&lt;br /&gt;
    From - Das ist die Absendeadresse und der dazugehörige Name. Es ist üblich diesen in der Form Name anzugeben. Das ist die absolute Minimumangabe für inen Mailheader. Fehlt das From, wird der Versand der Mail fehlschlagen.&lt;br /&gt;
    Reply-To - Das Format kann entweder nur eine Email Adresse sein, oder man wählt das Format wir bei From. Dieses Feld ist die Antwortadresse an die die Mail geschickt wird, wenn wir im Mail Client auf antworten klicken.&lt;br /&gt;
    Return-Path - Konnte die Mail nicht zugestellt werden, wird dies an diese Adresse gemeldet.&lt;br /&gt;
    MIME-Version - Entspricht dem MIME Typ der Mail.&lt;br /&gt;
    Content-Type - Das ist die Information die dem Mail Client mitteilt, um welche Art Mail es sich handelt und welcher Zeichensatz zur Darstellung benutzt werden soll.&lt;br /&gt;
    Content-Transfer-Encoding - Dies beschreibt die Art der Übertragung und wie sowohl Mailserver, als auch Email Clients diese Mail interpretieren. 7bit ist die kleinste Form, die maximal mögliche Kompatibilität ermöglicht. Beim 7bit ASCII Zeichensatz können die ersten 128 zeichen der ASCII Tabelle dargestellt werden. Zeichen wie deutsche Umlaute sind darin nicht vorgesehen. Bei der 8bit Übertragung können bis zu 256 zeichen dargestellt werden. Ältere Mailerver, so liest man, verstehen nur 7bit und verwerfen Anfragen die mit 8bit übertragen werden sollen. Anders ausgedrückt, es kann passieren das die Mail nicht ankommt. Ich persönlich hatte damit allerdings noch nie Probleme und die 7bit &amp;quot;Zwangsangabe&amp;quot; scheint veraltet zu sein.&lt;br /&gt;
    Message-ID - Die Message ID ist einmalig, bzw. sollte es sein, wodurch die Mail eindeutig zugeordnet werden kann.&lt;br /&gt;
    X-Mailer - Beschreibt den Client der die Mail versendet hat. In unserem Fall geben wir die PHP Version an, damit Mailserver auf der Route wissen, dass diese Mail mit PHP verschickt wurde.&lt;br /&gt;
&lt;br /&gt;
Es gibt noch weitere Felder und Varianten, die uns aber im moment nicht kümmern. Im Abschnitt Mail mit Anhang werden wir noch einen etwas anderen Header kennen lernen.&lt;br /&gt;
Speziell die letzten beiden Angaben (Message ID und X_Mailer) im Header oben sind sehr wichtige Informationen. Fehlen diese Angaben, ist die Wahrscheinlichkeit sehr hoch, dass die Mail niemals beim Empfänger ankommen wird, weil die Mail irgendwo unterwegs in einem Spamfilter hängen bleibt und nicht weitergeleitet wird!&lt;br /&gt;
&lt;br /&gt;
Falls also eine Mail nicht ankommt, liegt das in den aller meisten Fällen entweder am Transfer-Encoding (7bit oder 8bit) oder an fehlenden Absendeangaben!&lt;br /&gt;
&lt;br /&gt;
Der Rest des Scripts ist sehr einfach, weil hier einfach nur noch die Mail verschickt wird.&lt;br /&gt;
&lt;br /&gt;
    if (@mail( $empfaenger, htmlspecialchars( $betreff ), $mailbody, $mailheader ))&lt;br /&gt;
    {&lt;br /&gt;
        // Bei erfolgreichem Versand Danke-Seite anzeigen&lt;br /&gt;
        echo &amp;#039;Danke, die Email wurde verschickt!&amp;#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Die mail-Funktion kennt noch einen 5. Parameter auf den ich jetzt nicht eingehen werde, weil dieser nur in den seltensten Fällen unterstützt wird. Wer mehr darüber erfahren möchte kann sich darüber in der Online-Doku informieren. Die mail-Funktion selbst liefert entweder TRUE oder FALSE zurück. Bei einem FALSE konnte die Mail nicht für den Versand übergeben werden und wir können entsprechend darauf reagieren. Im Falle von TRUE heisst das zwar das die Mail für den Versand angenommen wurde, aber es ist nicht prüfbar ob die Mail auch tatsächlich beim Empfänger ankam! Einige Gründe dafür stehen weiter oben. Wurde die Mail für den Versand akzeptiert, können wir darauf angemessen reagieren, indem wir den Besucher zu einer Danke-Seite weiterleiten oder, was weiter unter gezeigt wird, dem Benutzer eine Empfangsbestätigung, respektive Kopie der Mail an seine Adresse schicken.&lt;br /&gt;
&lt;br /&gt;
Soweit so gut. Dieser Abschnitt fiel etwas länger aus, weil ich die prinzipielle Funktionsweise und den Header beschrieben habe. Die nachfolgenden Beispiele sind über große Strecken identisch, deswegen spare ich mir dort die Erklärungen und gehe nur auf die abweichenden Passagen ein.&lt;br /&gt;
&lt;br /&gt;
=== E-Mail mit CSS und Anhang ===&lt;br /&gt;
Todo Quelle siehe oben (2012-03)&lt;br /&gt;
&lt;br /&gt;
HTML Email mit CSS Formatierung und Dateianhang&lt;br /&gt;
&lt;br /&gt;
Da wir eine Datei mit der Mail verschicken möchten, muß das Formular natürlich dahingehend erweitert werden, dass ein Upload auch möglich ist. In unserem Beispiel möchten wir eine JPG datei anhängen und erlauben auch nur das hochladen dieses Bildtyps.&lt;br /&gt;
Die Template Datei ist identisch zum vorherigen HTML Beispiel. In der Datei funktionen.inc.php fügen wir aber eine weitere Funktion hinzu, die für uns prüft, ob eine Datei hochgeladen wurde und ob es sich dabei um eine JPG Datei handelt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function checkFile()&lt;br /&gt;
{&lt;br /&gt;
    if ($_FILES[&amp;#039;datei&amp;#039;][&amp;#039;error&amp;#039;] == 0 &amp;amp;&amp;amp;&lt;br /&gt;
        $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;type&amp;#039;] == &amp;#039;image/jpeg&amp;#039;)&lt;br /&gt;
    {&lt;br /&gt;
        return $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;name&amp;#039;];&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        die( &amp;#039;Bitte eine gültige JPG Datei anhängen!&amp;#039; );&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der Datei mail.php wird sich nun einiges ändern. Zunächst erweitern wir die einleitende Abfrage dahingehend, dass wir feststellen ob auch eine Datei angehängt wurde ...&lt;br /&gt;
&lt;br /&gt;
 if (isset($_POST[&amp;#039;senden&amp;#039;]) &amp;amp;&amp;amp; $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;size&amp;#039;] &amp;gt; 0)&lt;br /&gt;
&lt;br /&gt;
... und fügen ebenso den Aufruf für die neue Funktion hinzu, die prüft ob ein JPG hochgeladen wurde:&lt;br /&gt;
&lt;br /&gt;
 $uploadname = checkFile();&lt;br /&gt;
&lt;br /&gt;
Das weitere Listing der Datei mail.php sieht wie folgt aus:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // Template mit dem Mailbody laden&lt;br /&gt;
    $template = file_get_contents( &amp;#039;mailbody.txt&amp;#039; );&lt;br /&gt;
    // Trenner für den Anhang&lt;br /&gt;
    $trenner = md5( time() );&lt;br /&gt;
 &lt;br /&gt;
    // Platzhalter mit den Benutzereingaben ersetzen&lt;br /&gt;
    $template = str_replace( &amp;#039;###NAME###&amp;#039;, htmlspecialchars( $name ), $template );&lt;br /&gt;
    $template = str_replace( &amp;#039;###EMAIL###&amp;#039;, $email, $template );&lt;br /&gt;
    $template = str_replace( &amp;#039;###NACHRICHT###&amp;#039;, nl2br( htmlspecialchars( $nachricht ) ), $template );&lt;br /&gt;
 &lt;br /&gt;
    // Mail Header erstellen&lt;br /&gt;
    $mailheader .= &amp;quot;Reply-To: &amp;quot; .$name. &amp;quot;&amp;lt;&amp;quot; .$email. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Return-Path: noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Message-ID: &amp;lt;&amp;quot; .time(). &amp;quot; noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;X-Mailer: PHP v&amp;quot; .phpversion(). &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;From: PHP Email Tutorial&amp;lt;noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;MIME-Version: 1.0\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Type: multipart/mixed;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot; boundary = &amp;quot; .$trenner;&lt;br /&gt;
    $mailheader .= &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    // Mailbody vorbereiten&lt;br /&gt;
    $mailbody  = &amp;quot;This is a multi-part message in MIME format\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;--&amp;quot; .$trenner. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Type: text/html; charset=UTF-8\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Transfer-Encoding: 8bit\r\n\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= $template. &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    // Anhang anfügen&lt;br /&gt;
    $mailbody .= &amp;quot;--&amp;quot; .$trenner. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Type: image/jpeg; name=\&amp;quot;&amp;quot; .$uploadname. &amp;quot;\&amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Transfer-Encoding: base64\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Disposition: attachment; filename=\&amp;quot;&amp;quot; .$uploadname. &amp;quot;\&amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= chunk_split( base64_encode( file_get_contents( $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;tmp_name&amp;#039;] ) ) );&lt;br /&gt;
    $mailbody .= &amp;quot;\n&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    // Email versenden&lt;br /&gt;
    if (@mail( $empfaenger, htmlspecialchars( $betreff ), $mailbody, $mailheader ))&lt;br /&gt;
    {&lt;br /&gt;
        // Bei erfolgreichem Versand Danke-Seite anzeigen&lt;br /&gt;
        echo &amp;#039;Danke, die Email wurde verschickt!&amp;#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen auf den ersten Blick, dass dieser Code ganz anders aussieht als das vorherige Beispiel. Gehen wir den Code mal der Reihe nach durch, um etwas Licht in&amp;#039;s Dunkel zu bringen.&lt;br /&gt;
&lt;br /&gt;
Im oberen Bereich erzeugen wir einen eindeutigen String, den wir zum trennen der verschiedenen Teilbereiche der Mail verwenden werden:&lt;br /&gt;
&lt;br /&gt;
 $trenner = md5( time() );&lt;br /&gt;
&lt;br /&gt;
Der erste Teil des Mail Header ist uns bereits bekannt, aber beim Content-Type benötigen wir nun eine andere Angabe.&lt;br /&gt;
&lt;br /&gt;
 $mailheader .= &amp;quot;Content-Type: multipart/mixed;\r\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
Dieser Content-Type ähnelt der Angabe &amp;quot;multipart/form-data&amp;quot; in einem HTML Formular, wenn wir dort ebenfalls gemischte Inhalte haben, nämlich Text und Dateien. Damit der Mail Client nun weiß an welchen Stellen im gesendeten Quellcode er Inhalte trennen muß, teilen wir im Header den boundary-String mit.&lt;br /&gt;
&lt;br /&gt;
An dieser Stelle möchte ich noch auf 2 wichtige Dinge hinweisen. Das Leerzeichen vor dem &amp;quot;boundary&amp;quot; im Header ist kein Versehen! Es kann tatsächlich dazu führen das eine Mail nicht korrekt dargestellt wird, wenn dieses Leerzeichen fehlt. Ebenso ist es wichtig, dass die &amp;quot;From&amp;quot;-Angabe unmittelbar vor der &amp;quot;MIME-Version&amp;quot; und dem &amp;quot;Content-Type&amp;quot; steht. Vertauscht man die Reihenfolge der Header Angabe, führt das z.B. bei mir dazu, dass ich im Thunderbird nur eine leere Seite als Mail angezeigt bekomme, obwohl der komplette Mail Inhalt im Quelltext einsehbar ist.&lt;br /&gt;
&lt;br /&gt;
Die nächste Zeile ...&lt;br /&gt;
&lt;br /&gt;
 $mailbody  = &amp;quot;This is a multi-part message in MIME format\r\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
... steht vor der Nachricht im Head Bereich in der Email. Sie scheint nicht zwingend erforderlich zu sein, aber Mail Clients fügen diese ebenfalls hinzu, wenn man mit z.B. Thunderbird eine Email verschickt. Ich vermute, dass dies aus Gründen der Kompatibilität zu einigen Mail Server geschieht.&lt;br /&gt;
&lt;br /&gt;
Nun folgt der erste Teil unserer Email, der Text.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    $mailbody .= &amp;quot;--&amp;quot; .$trenner. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Type: text/html; charset=UTF-8\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Transfer-Encoding: 8bit\r\n\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= $template. &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Durch den Trenner teilen wir dem Mail Client mit, dass zwischen diesem Trenner und dem nächsten Trenner, bzw. dem Ende der Mail, ein Teilabschnitt dieser Email steht. Damit der Client weiß um was es sich bei diesem Abschnitt handelt, teilen wir ihm das mithilfe des &amp;quot;Content-Type&amp;quot; und dem &amp;quot;Transfer-Encoding&amp;quot; mit. Durch die Angabe &amp;quot;text/html&amp;quot; weiß nun der Client, dass alles bis zum nächsten Trennen als HTML dargestellt werden soll.&lt;br /&gt;
&lt;br /&gt;
Der nächste Teilabschnitt der Mail ist unser Bild:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // Anhang anfügen&lt;br /&gt;
    $mailbody .= &amp;quot;--&amp;quot; .$trenner. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Type: image/jpeg; name=\&amp;quot;&amp;quot; .$uploadname. &amp;quot;\&amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Transfer-Encoding: base64\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Disposition: attachment; filename=\&amp;quot;&amp;quot; .$uploadname. &amp;quot;\&amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= chunk_split( base64_encode( file_get_contents( $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;tmp_name&amp;#039;] ) ) );&lt;br /&gt;
    $mailbody .= &amp;quot;\n&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wieder folgt zunächst der Trenner. Der Client stoppt seine HTML Ausgabe an dieser Position und wird ab diesem Punkt ausgeben, was ihm durch den &amp;quot;Content-Type&amp;quot; und das &amp;quot;Transfer-Encoding&amp;quot; aufgetragen wird. Wir sehen nun, dass wir als Content-Type eine JPG Datei ausgeben möchten. Der Name ergibt sich aus dem Rückgabewert der Funktion, die den Upload zuvor überprüft hat. Als Transfer-Encoding wird &amp;quot;base64&amp;quot; angegeben. Diese Angabe ist überaus wichtig um eine korrekte Übertragung der Daten zu gewährleisten. Mit der Angabe &amp;quot;Content-Disposition: attachment;&amp;quot; legen wir fest, dass der Anhang wirklich an die Mail angehängt wird. Eine andere Möglichkeit wäre hier das Einbetten in den Mailtext, indem man als Content-Disposition ein &amp;quot;inline&amp;quot; angibt. Die nächste Zeile ist ziemlich tricky:&lt;br /&gt;
&lt;br /&gt;
 $mailbody .= chunk_split( base64_encode( file_get_contents( $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;tmp_name&amp;#039;] ) ) );&lt;br /&gt;
&lt;br /&gt;
Arbeiten wir uns mal von Innen nach Außen durch, weil hier mehrere Funktionen verschachtelt sind. Mit file_get_contents wird eine Datei als String eingelesen. Dies ist hier möglich, weil diese Funktion seit PHP 4.3 binary safe ist. Als einzulesender Dateiname nehmen wir hier den Name der temporären datei, die durch den Upload auf dem Server gelandet ist. Diese Datei steht nur zu genau diesem Zeitpunkt zur Verfügung. Sobald das Script beendet wird oder eine andere Seite geladen wird, existiert diese Datei nicht mehr. Möchte man diese Datei erst zu einem späteren Zeitpunkt verarbeiten, muß man diese zunächst mit move_uploaded_file an eine andere Position kopieren.&lt;br /&gt;
Da wir nun die Bilddatei als String eingelesen haben, wird er mit base64_encode umgewandelt, damit die Datei beschädigt wird, falls es nicht möglich ist die Mail als 8bit zu übertragen. Es wird also aus Gründen der Kompatibilität gemacht. Anschließend wird der String mit chunk_split so aufbereitet, dass die Zeilenlänge 76 Zeichen nicht übersteigt.&lt;br /&gt;
&lt;br /&gt;
Das war&amp;#039;s! Die Daten können nun wieder mit der mail-Funktion versendet werden. Sollte man mehr als eine Datei anhängen wollen, kann man den letzten Schritt beliebig oft wiederholen. Erst Trenner setzen, dann Art der Daten und Übertragungsmodus angeben, die Datei anhängen, fertig.&lt;/div&gt;</summary>
		<author><name>178.7.132.100</name></author>
	</entry>
	<entry>
		<id>https://wiki.stephanschlegel.de/index.php?title=PHP_-_Validieren_von_Benutzereingaben&amp;diff=19049</id>
		<title>PHP - Validieren von Benutzereingaben</title>
		<link rel="alternate" type="text/html" href="https://wiki.stephanschlegel.de/index.php?title=PHP_-_Validieren_von_Benutzereingaben&amp;diff=19049"/>
		<updated>2012-03-13T10:39:09Z</updated>

		<summary type="html">&lt;p&gt;178.7.132.100: Die Seite wurde neu angelegt: „ == Beispielfunktionen für die Validierung in PHP ==  Quelle: http://www.phpbuddy.eu/emails-mit-php-versenden.html?start=1 2012-03  &amp;lt;pre&amp;gt; &amp;lt;?php   header( &amp;#039;Conten…“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Beispielfunktionen für die Validierung in PHP ==&lt;br /&gt;
&lt;br /&gt;
Quelle: http://www.phpbuddy.eu/emails-mit-php-versenden.html?start=1 2012-03&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
 &lt;br /&gt;
header( &amp;#039;Content-Type: text/html; charset=utf-8&amp;#039; );&lt;br /&gt;
 &lt;br /&gt;
// Benutzereingabe bereinigen (trimmen, Slashes entfernen)&lt;br /&gt;
function cleanInput()&lt;br /&gt;
{&lt;br /&gt;
    checkInjection();&lt;br /&gt;
    if (get_magic_quotes_gpc()) $_POST = array_map( &amp;#039;stripslashes&amp;#039;, $_POST );&lt;br /&gt;
    $_POST = array_map( &amp;#039;trim&amp;#039;, $_POST );&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
// Name auf Gültigkeit prüfen&lt;br /&gt;
function checkName( $name )&lt;br /&gt;
{&lt;br /&gt;
    $muster_name = &amp;#039;/^([a-zA-ZäÄöÖüÜß\xc0-\xc2\xc8-\xcf\xd2-\xd4\xd9-\xdb\xe0-\xe2\xe8-\xef\xf2-\xf4\xf9-\xfb\x9f\xff\.\&amp;#039;\-_]?(\s)?)+$/&amp;#039;;&lt;br /&gt;
    if (preg_match( $muster_name, $name ))&lt;br /&gt;
    {&lt;br /&gt;
        return $name;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        die( &amp;#039;Der eingegebene Name enthält nicht erlaubte Zeichen!&amp;#039; );&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
// Email auf korrektes Format prüfen&lt;br /&gt;
function checkEmail( $email )&lt;br /&gt;
{&lt;br /&gt;
    $nonascii      = &amp;quot;\x80-\xff&amp;quot;;    &lt;br /&gt;
    $nqtext        = &amp;quot;[^\\\\$nonascii\015\012\&amp;quot;]&amp;quot;;&lt;br /&gt;
    $qchar         = &amp;quot;\\\\[^$nonascii]&amp;quot;;&lt;br /&gt;
    $normuser      = &amp;#039;[a-zA-Z0-9][a-zA-Z0-9_.-]*&amp;#039;;&lt;br /&gt;
    $quotedstring  = &amp;quot;\&amp;quot;(?:$nqtext|$qchar)+\&amp;quot;&amp;quot;;&lt;br /&gt;
    $user_part     = &amp;quot;(?:$normuser|$quotedstring)&amp;quot;;&lt;br /&gt;
    $dom_mainpart  = &amp;#039;[a-zA-Z0-9][a-zA-Z0-9._-]*\\.&amp;#039;;&lt;br /&gt;
    $dom_subpart   = &amp;#039;(?:[a-zA-Z0-9][a-zA-Z0-9._-]*\\.)*&amp;#039;;&lt;br /&gt;
    $dom_tldpart   = &amp;#039;[a-zA-Z]{2,5}&amp;#039;;&lt;br /&gt;
    $domain_part   = &amp;quot;$dom_subpart$dom_mainpart$dom_tldpart&amp;quot;;&lt;br /&gt;
    $pattern       = &amp;quot;$user_part\@$domain_part&amp;quot;;&lt;br /&gt;
    $muster_email  = &amp;quot;/^{$pattern}$/&amp;quot;;&lt;br /&gt;
    if (preg_match( $muster_email, $email ))&lt;br /&gt;
    {&lt;br /&gt;
        return $email;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        die( &amp;#039;Die eingegebene Email-Adresse hat kein gültiges Format!&amp;#039; );&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
// Benutzereingaben auf mögliche Injection prüfen&lt;br /&gt;
function checkInjection()&lt;br /&gt;
{&lt;br /&gt;
    $email_injection = array( &amp;#039;bcc:&amp;#039;, &amp;#039;boundary&amp;#039;, &amp;#039;cc:&amp;#039;, &amp;#039;content-transfer-encoding:&amp;#039;, &amp;#039;content-type:&amp;#039;, &amp;#039;mime-version:&amp;#039;, &amp;#039;subject:&amp;#039; );&lt;br /&gt;
 &lt;br /&gt;
    // Auf potentielle Email Injections prüfen&lt;br /&gt;
    foreach ($email_injection as $injection)&lt;br /&gt;
    {&lt;br /&gt;
        foreach ($_POST as $feld =&amp;gt; $inhalt)&lt;br /&gt;
        {&lt;br /&gt;
            if (preg_match( &amp;quot;/{$injection}/i&amp;quot;, $inhalt ))&lt;br /&gt;
            {&lt;br /&gt;
                header( &amp;#039;location: http://www.google.com/search?hl=en&amp;amp;q=how+to+become+a+better+hacker&amp;#039; );&lt;br /&gt;
                exit;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return true;&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>178.7.132.100</name></author>
	</entry>
	<entry>
		<id>https://wiki.stephanschlegel.de/index.php?title=PHP_-_Tipps_und_Tricks&amp;diff=19048</id>
		<title>PHP - Tipps und Tricks</title>
		<link rel="alternate" type="text/html" href="https://wiki.stephanschlegel.de/index.php?title=PHP_-_Tipps_und_Tricks&amp;diff=19048"/>
		<updated>2012-03-13T10:37:55Z</updated>

		<summary type="html">&lt;p&gt;178.7.132.100: /* E-Mails mit php versenden */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Links ==&lt;br /&gt;
http://www.phpbuddy.eu/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== E-Mails mit php versenden ==&lt;br /&gt;
[[PHP - E-Mail versenden]]&lt;br /&gt;
&lt;br /&gt;
siehe auch &lt;br /&gt;
&lt;br /&gt;
[[PHP - Validieren von Benutzereingaben]]&lt;br /&gt;
&lt;br /&gt;
== Bilder schützen und nur über php ausliefern ==&lt;br /&gt;
1a Schutz per htaccess, so daß nur Zugriffe vom eigenen Server zulässig sind.&lt;br /&gt;
1b. Verzeichnisrechte so setzen, daß nur php-Nutzer lesen kann (oder einfach ein schwer zu erratender Verzeichnisname) -&amp;gt; kann man aber z.B. mit iFrame umgehen ist also weniger als Schutz praktisch, reicht aber, wenn man zur Laufzeit eine andere Variante des Bildes liefern will.&lt;br /&gt;
2. PHP Skript liefert die Bilder -&amp;gt; hier kann man dann User Access, Zeitsteuerung etc. regeln.&lt;br /&gt;
&lt;br /&gt;
Beispiel htaccess:&lt;br /&gt;
&lt;br /&gt;
Zugriff auf das Verzeichnis nur über php nicht über direktzugriff &lt;br /&gt;
&lt;br /&gt;
 order deny,allow&lt;br /&gt;
 deny  from all&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hierbei sind auf Bilder nur Zugriffe von der eigenen Domain erlaubt, ansonsten kommt ein Ersatzbild. Eignet sich z.B. um Traffic durch Bilderklau vorzubeugen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RewriteEngine on&lt;br /&gt;
RewriteCond %{HTTP_REFERER} !^$&lt;br /&gt;
RewriteCond %{HTTP_REFERER} !^http://(www.)?mydomain.de(/.*)?$ [NC]&lt;br /&gt;
RewriteRule .(gif|jpg|GIF|JPG)$ http://www.myDomain.de/images/ersatz.gif [R,L]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if ($_SESSION[&amp;#039;eingeloggt&amp;#039;] == true) {&lt;br /&gt;
   header(&amp;#039;Content-Type: image/jpeg&amp;#039;);&lt;br /&gt;
   readfile(&amp;#039;bild.jpg&amp;#039;);&lt;br /&gt;
} else {&lt;br /&gt;
   echo &amp;#039;Kein Direktzugriff erlaubt&amp;#039;; &lt;br /&gt;
}&lt;br /&gt;
?&amp;gt; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Weitere Beispiele mit htaccess:&lt;br /&gt;
&lt;br /&gt;
Beispiel mit Ersatzgrafik und mehreren URL&amp;#039;s:&lt;br /&gt;
Kann ja sein, dass man mehrere Homepages hat, die darauf zurückgreifen dürfen. Folgendes überträgst Du ins Notepad und speicherst es als .htaccess ab:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     RewriteEngine on&lt;br /&gt;
     RewriteCond %{HTTP_REFERER} !^$&lt;br /&gt;
     RewriteCond %{HTTP_REFERER} !^http://(www.)?webmaster-eye.de(/.*)?$ [NC]&lt;br /&gt;
     RewriteCond %{HTTP_REFERER} !^http://(www.)?mynickpage.de(/.*)?$ [NC]&lt;br /&gt;
     RewriteRule .(gif|jpg|GIF|JPG)$ http://www.webmaster-eye.de/images/ersatz.gif [R,L]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beispiel mit dem roten X:&lt;br /&gt;
Folgendes überträgst Du ins Notepad und speicherst es als .htaccess ab:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     RewriteEngine on&lt;br /&gt;
     RewriteCond %{HTTP_REFERER} !^$&lt;br /&gt;
     RewriteCond %{HTTP_REFERER} !^http://(www.)?webmaster-eye.de(/.*)?$ [NC]&lt;br /&gt;
     RewriteRule .(gif|jpg)$ - [F]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quelle der htaccess Beispiele: http://www.webmaster-eye.de/Traffic-sparen-mit-htaccess-als-Bilder-Schutz.242.artikel.html (11/2011)&lt;br /&gt;
&lt;br /&gt;
== Weiterleitung mit PHP ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 header(&amp;quot;Location: http://www.myHomepage.net&amp;quot;);&lt;br /&gt;
 exit;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Ausgaben zwischenspeichern oder in Variablen umleiten ==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Problem: Die Ausgabe von echo oder von includes soll zuerst in einer Variablen gespeichert werden, damit Sie nicht gleich ausgegeben werden.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 &lt;br /&gt;
Das läßt sich lösen indem man die Ausgabe zunächst puffert und dann den Puffer in eine Variable lädt.&lt;br /&gt;
 basicartsstudios at hotmail dot com&lt;br /&gt;
21-Jan-2007 10:39&lt;br /&gt;
Sometimes you might not want to include a php-file under the specifications defined in the functions include() or require(), but you might want to have in return the string that the script in the file &amp;quot;echoes&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Include() and require() both directly put out the evaluated code.&lt;br /&gt;
&lt;br /&gt;
For avoiding this, try output-buffering:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
ob_start();&lt;br /&gt;
eval(file_get_contents($file));&lt;br /&gt;
$result = ob_get_contents();&lt;br /&gt;
ob_end_clean();&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
ob_start();&lt;br /&gt;
include($file);&lt;br /&gt;
$result = ob_get_contents();&lt;br /&gt;
ob_end_clean();&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which i consider the same, correct me if I&amp;#039;m wrong.&lt;br /&gt;
&lt;br /&gt;
Best regards, BasicArtsStudios&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Umlaute, UTF-8 und PHP: wenn Sonderzeichen falsch dargestellt werden ==&lt;br /&gt;
Quelle: http://www.sjmfreelancing.de/devblog/umlaute-utf-8-und-php.html (15.10.2008)&lt;br /&gt;
&lt;br /&gt;
Ich habe des öfteren das Problem gehabt, dass Sonderzeichen auf PHP-basierten Internetseiten nicht korrekt angezeigt wurden und Firefox ein gerahmtes Fragezeichen statt Ü, ü etc. ausgab, der Internet Explorer einen Kasten und auch Safari&amp;amp;Co. Probleme hatten.&lt;br /&gt;
&lt;br /&gt;
Lange war ich auf der Suche nach der richtigen Lösung für dieses Problem und habe mich durch unterschiedliche Blogs, Foren und Internetseiten gewühlt bis ich letztendlich eine Ansammlung verschiedenster Tipps &amp;amp; Tricks aufgenommen und in Kombination angewandt habe. Und siehe da: Sonderzeichen sind korrekt :)&lt;br /&gt;
&lt;br /&gt;
Hier ein paar Dinge, die jeder Programmierer beherzigen sollte, wenn er mit Umlauten umgeht:&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1. Header korrekt setzen&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Mit einem Einzeiler kann man PHP dazu bringen einen UTF-8-Header an den Browser zu senden. Einfach folgenden Code ganz oben in der Index-Datei setzen:&lt;br /&gt;
&lt;br /&gt;
 header(&amp;#039;content-type: text/html; charset=UTF-8&amp;#039;);  &lt;br /&gt;
&lt;br /&gt;
2. HTML-Header korrekt setzen&lt;br /&gt;
&lt;br /&gt;
Folgenden Code in den HEAD-Bereich des HTML-Dokuments setzen:&lt;br /&gt;
view plaincopy to clipboardprint?&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=UTF-8&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. PHP-Dateien im UTF-8-Format speichern&lt;br /&gt;
&lt;br /&gt;
Ganz wichtig ist es die PHP-Dateien die man verwendet im UTF-8-Format zu speichern. Sprich: den Editor dazu zu bringen, die Datei mit Umlauten zu speichern.&lt;br /&gt;
4. MySQL dazu bewegen UTF-8 zu nutzen&lt;br /&gt;
&lt;br /&gt;
MySQL liefert auch nicht (immer) von Haus aus UTF-8-korrekte Ausgaben. Folgendes MySQL-Query einfach nach dem connecten mit der Datenbank ausführen:&lt;br /&gt;
&lt;br /&gt;
 mysql_query(&amp;#039;set character set utf8;&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
5. Das &amp;amp;-Zeichen immer escapen&lt;br /&gt;
&lt;br /&gt;
Zwar nicht direkt ein Problem, aber: ü, ä, ß etc. sind auch dann korrektes HTML, wenn man sie nicht mittels htmlentities in Entitäten umgewandelt hat. Anders sieht es mit dem Kaufmanns-Und (&amp;amp;) aus: diesen IMMER mit &amp;amp;amp; ausgeben. Auch bei Links gilt: &amp;amp; durch &amp;lt;code&amp;gt;&amp;amp;amp;&amp;lt;/code&amp;gt; ersetzen!&lt;br /&gt;
&lt;br /&gt;
== Validieren von Werten aus Eingabefeldern ==&lt;br /&gt;
[[PHP - Validierung von Werten aus Eingabefeldern]]&lt;br /&gt;
&lt;br /&gt;
== Sicherheit in PHP Skripts ==&lt;/div&gt;</summary>
		<author><name>178.7.132.100</name></author>
	</entry>
	<entry>
		<id>https://wiki.stephanschlegel.de/index.php?title=PHP_-_Tipps_und_Tricks&amp;diff=19047</id>
		<title>PHP - Tipps und Tricks</title>
		<link rel="alternate" type="text/html" href="https://wiki.stephanschlegel.de/index.php?title=PHP_-_Tipps_und_Tricks&amp;diff=19047"/>
		<updated>2012-03-13T10:35:20Z</updated>

		<summary type="html">&lt;p&gt;178.7.132.100: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Links ==&lt;br /&gt;
http://www.phpbuddy.eu/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== E-Mails mit php versenden ==&lt;br /&gt;
[[PHP - E-Mail versenden]]&lt;br /&gt;
&lt;br /&gt;
== Bilder schützen und nur über php ausliefern ==&lt;br /&gt;
1a Schutz per htaccess, so daß nur Zugriffe vom eigenen Server zulässig sind.&lt;br /&gt;
1b. Verzeichnisrechte so setzen, daß nur php-Nutzer lesen kann (oder einfach ein schwer zu erratender Verzeichnisname) -&amp;gt; kann man aber z.B. mit iFrame umgehen ist also weniger als Schutz praktisch, reicht aber, wenn man zur Laufzeit eine andere Variante des Bildes liefern will.&lt;br /&gt;
2. PHP Skript liefert die Bilder -&amp;gt; hier kann man dann User Access, Zeitsteuerung etc. regeln.&lt;br /&gt;
&lt;br /&gt;
Beispiel htaccess:&lt;br /&gt;
&lt;br /&gt;
Zugriff auf das Verzeichnis nur über php nicht über direktzugriff &lt;br /&gt;
&lt;br /&gt;
 order deny,allow&lt;br /&gt;
 deny  from all&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hierbei sind auf Bilder nur Zugriffe von der eigenen Domain erlaubt, ansonsten kommt ein Ersatzbild. Eignet sich z.B. um Traffic durch Bilderklau vorzubeugen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RewriteEngine on&lt;br /&gt;
RewriteCond %{HTTP_REFERER} !^$&lt;br /&gt;
RewriteCond %{HTTP_REFERER} !^http://(www.)?mydomain.de(/.*)?$ [NC]&lt;br /&gt;
RewriteRule .(gif|jpg|GIF|JPG)$ http://www.myDomain.de/images/ersatz.gif [R,L]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if ($_SESSION[&amp;#039;eingeloggt&amp;#039;] == true) {&lt;br /&gt;
   header(&amp;#039;Content-Type: image/jpeg&amp;#039;);&lt;br /&gt;
   readfile(&amp;#039;bild.jpg&amp;#039;);&lt;br /&gt;
} else {&lt;br /&gt;
   echo &amp;#039;Kein Direktzugriff erlaubt&amp;#039;; &lt;br /&gt;
}&lt;br /&gt;
?&amp;gt; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Weitere Beispiele mit htaccess:&lt;br /&gt;
&lt;br /&gt;
Beispiel mit Ersatzgrafik und mehreren URL&amp;#039;s:&lt;br /&gt;
Kann ja sein, dass man mehrere Homepages hat, die darauf zurückgreifen dürfen. Folgendes überträgst Du ins Notepad und speicherst es als .htaccess ab:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     RewriteEngine on&lt;br /&gt;
     RewriteCond %{HTTP_REFERER} !^$&lt;br /&gt;
     RewriteCond %{HTTP_REFERER} !^http://(www.)?webmaster-eye.de(/.*)?$ [NC]&lt;br /&gt;
     RewriteCond %{HTTP_REFERER} !^http://(www.)?mynickpage.de(/.*)?$ [NC]&lt;br /&gt;
     RewriteRule .(gif|jpg|GIF|JPG)$ http://www.webmaster-eye.de/images/ersatz.gif [R,L]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beispiel mit dem roten X:&lt;br /&gt;
Folgendes überträgst Du ins Notepad und speicherst es als .htaccess ab:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     RewriteEngine on&lt;br /&gt;
     RewriteCond %{HTTP_REFERER} !^$&lt;br /&gt;
     RewriteCond %{HTTP_REFERER} !^http://(www.)?webmaster-eye.de(/.*)?$ [NC]&lt;br /&gt;
     RewriteRule .(gif|jpg)$ - [F]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quelle der htaccess Beispiele: http://www.webmaster-eye.de/Traffic-sparen-mit-htaccess-als-Bilder-Schutz.242.artikel.html (11/2011)&lt;br /&gt;
&lt;br /&gt;
== Weiterleitung mit PHP ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 header(&amp;quot;Location: http://www.myHomepage.net&amp;quot;);&lt;br /&gt;
 exit;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Ausgaben zwischenspeichern oder in Variablen umleiten ==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Problem: Die Ausgabe von echo oder von includes soll zuerst in einer Variablen gespeichert werden, damit Sie nicht gleich ausgegeben werden.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 &lt;br /&gt;
Das läßt sich lösen indem man die Ausgabe zunächst puffert und dann den Puffer in eine Variable lädt.&lt;br /&gt;
 basicartsstudios at hotmail dot com&lt;br /&gt;
21-Jan-2007 10:39&lt;br /&gt;
Sometimes you might not want to include a php-file under the specifications defined in the functions include() or require(), but you might want to have in return the string that the script in the file &amp;quot;echoes&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Include() and require() both directly put out the evaluated code.&lt;br /&gt;
&lt;br /&gt;
For avoiding this, try output-buffering:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
ob_start();&lt;br /&gt;
eval(file_get_contents($file));&lt;br /&gt;
$result = ob_get_contents();&lt;br /&gt;
ob_end_clean();&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
ob_start();&lt;br /&gt;
include($file);&lt;br /&gt;
$result = ob_get_contents();&lt;br /&gt;
ob_end_clean();&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which i consider the same, correct me if I&amp;#039;m wrong.&lt;br /&gt;
&lt;br /&gt;
Best regards, BasicArtsStudios&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Umlaute, UTF-8 und PHP: wenn Sonderzeichen falsch dargestellt werden ==&lt;br /&gt;
Quelle: http://www.sjmfreelancing.de/devblog/umlaute-utf-8-und-php.html (15.10.2008)&lt;br /&gt;
&lt;br /&gt;
Ich habe des öfteren das Problem gehabt, dass Sonderzeichen auf PHP-basierten Internetseiten nicht korrekt angezeigt wurden und Firefox ein gerahmtes Fragezeichen statt Ü, ü etc. ausgab, der Internet Explorer einen Kasten und auch Safari&amp;amp;Co. Probleme hatten.&lt;br /&gt;
&lt;br /&gt;
Lange war ich auf der Suche nach der richtigen Lösung für dieses Problem und habe mich durch unterschiedliche Blogs, Foren und Internetseiten gewühlt bis ich letztendlich eine Ansammlung verschiedenster Tipps &amp;amp; Tricks aufgenommen und in Kombination angewandt habe. Und siehe da: Sonderzeichen sind korrekt :)&lt;br /&gt;
&lt;br /&gt;
Hier ein paar Dinge, die jeder Programmierer beherzigen sollte, wenn er mit Umlauten umgeht:&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1. Header korrekt setzen&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Mit einem Einzeiler kann man PHP dazu bringen einen UTF-8-Header an den Browser zu senden. Einfach folgenden Code ganz oben in der Index-Datei setzen:&lt;br /&gt;
&lt;br /&gt;
 header(&amp;#039;content-type: text/html; charset=UTF-8&amp;#039;);  &lt;br /&gt;
&lt;br /&gt;
2. HTML-Header korrekt setzen&lt;br /&gt;
&lt;br /&gt;
Folgenden Code in den HEAD-Bereich des HTML-Dokuments setzen:&lt;br /&gt;
view plaincopy to clipboardprint?&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=UTF-8&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. PHP-Dateien im UTF-8-Format speichern&lt;br /&gt;
&lt;br /&gt;
Ganz wichtig ist es die PHP-Dateien die man verwendet im UTF-8-Format zu speichern. Sprich: den Editor dazu zu bringen, die Datei mit Umlauten zu speichern.&lt;br /&gt;
4. MySQL dazu bewegen UTF-8 zu nutzen&lt;br /&gt;
&lt;br /&gt;
MySQL liefert auch nicht (immer) von Haus aus UTF-8-korrekte Ausgaben. Folgendes MySQL-Query einfach nach dem connecten mit der Datenbank ausführen:&lt;br /&gt;
&lt;br /&gt;
 mysql_query(&amp;#039;set character set utf8;&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
5. Das &amp;amp;-Zeichen immer escapen&lt;br /&gt;
&lt;br /&gt;
Zwar nicht direkt ein Problem, aber: ü, ä, ß etc. sind auch dann korrektes HTML, wenn man sie nicht mittels htmlentities in Entitäten umgewandelt hat. Anders sieht es mit dem Kaufmanns-Und (&amp;amp;) aus: diesen IMMER mit &amp;amp;amp; ausgeben. Auch bei Links gilt: &amp;amp; durch &amp;lt;code&amp;gt;&amp;amp;amp;&amp;lt;/code&amp;gt; ersetzen!&lt;br /&gt;
&lt;br /&gt;
== Validieren von Werten aus Eingabefeldern ==&lt;br /&gt;
[[PHP - Validierung von Werten aus Eingabefeldern]]&lt;br /&gt;
&lt;br /&gt;
== Sicherheit in PHP Skripts ==&lt;/div&gt;</summary>
		<author><name>178.7.132.100</name></author>
	</entry>
	<entry>
		<id>https://wiki.stephanschlegel.de/index.php?title=PHP_-_E-Mail_versenden&amp;diff=19046</id>
		<title>PHP - E-Mail versenden</title>
		<link rel="alternate" type="text/html" href="https://wiki.stephanschlegel.de/index.php?title=PHP_-_E-Mail_versenden&amp;diff=19046"/>
		<updated>2012-03-13T10:33:42Z</updated>

		<summary type="html">&lt;p&gt;178.7.132.100: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Links&lt;br /&gt;
&lt;br /&gt;
http://www.phpbuddy.eu/emails-mit-php-versenden.html?start=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== E-Mail mit CSS und Anhang ===&lt;br /&gt;
Todo Quelle siehe oben (2012-03)&lt;br /&gt;
&lt;br /&gt;
HTML Email mit CSS Formatierung und Dateianhang&lt;br /&gt;
&lt;br /&gt;
Da wir eine Datei mit der Mail verschicken möchten, muß das Formular natürlich dahingehend erweitert werden, dass ein Upload auch möglich ist. In unserem Beispiel möchten wir eine JPG datei anhängen und erlauben auch nur das hochladen dieses Bildtyps.&lt;br /&gt;
Die Template Datei ist identisch zum vorherigen HTML Beispiel. In der Datei funktionen.inc.php fügen wir aber eine weitere Funktion hinzu, die für uns prüft, ob eine Datei hochgeladen wurde und ob es sich dabei um eine JPG Datei handelt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function checkFile()&lt;br /&gt;
{&lt;br /&gt;
    if ($_FILES[&amp;#039;datei&amp;#039;][&amp;#039;error&amp;#039;] == 0 &amp;amp;&amp;amp;&lt;br /&gt;
        $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;type&amp;#039;] == &amp;#039;image/jpeg&amp;#039;)&lt;br /&gt;
    {&lt;br /&gt;
        return $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;name&amp;#039;];&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        die( &amp;#039;Bitte eine gültige JPG Datei anhängen!&amp;#039; );&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der Datei mail.php wird sich nun einiges ändern. Zunächst erweitern wir die einleitende Abfrage dahingehend, dass wir feststellen ob auch eine Datei angehängt wurde ...&lt;br /&gt;
&lt;br /&gt;
 if (isset($_POST[&amp;#039;senden&amp;#039;]) &amp;amp;&amp;amp; $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;size&amp;#039;] &amp;gt; 0)&lt;br /&gt;
&lt;br /&gt;
... und fügen ebenso den Aufruf für die neue Funktion hinzu, die prüft ob ein JPG hochgeladen wurde:&lt;br /&gt;
&lt;br /&gt;
 $uploadname = checkFile();&lt;br /&gt;
&lt;br /&gt;
Das weitere Listing der Datei mail.php sieht wie folgt aus:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // Template mit dem Mailbody laden&lt;br /&gt;
    $template = file_get_contents( &amp;#039;mailbody.txt&amp;#039; );&lt;br /&gt;
    // Trenner für den Anhang&lt;br /&gt;
    $trenner = md5( time() );&lt;br /&gt;
 &lt;br /&gt;
    // Platzhalter mit den Benutzereingaben ersetzen&lt;br /&gt;
    $template = str_replace( &amp;#039;###NAME###&amp;#039;, htmlspecialchars( $name ), $template );&lt;br /&gt;
    $template = str_replace( &amp;#039;###EMAIL###&amp;#039;, $email, $template );&lt;br /&gt;
    $template = str_replace( &amp;#039;###NACHRICHT###&amp;#039;, nl2br( htmlspecialchars( $nachricht ) ), $template );&lt;br /&gt;
 &lt;br /&gt;
    // Mail Header erstellen&lt;br /&gt;
    $mailheader .= &amp;quot;Reply-To: &amp;quot; .$name. &amp;quot;&amp;lt;&amp;quot; .$email. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Return-Path: noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Message-ID: &amp;lt;&amp;quot; .time(). &amp;quot; noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;X-Mailer: PHP v&amp;quot; .phpversion(). &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;From: PHP Email Tutorial&amp;lt;noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;MIME-Version: 1.0\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Type: multipart/mixed;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot; boundary = &amp;quot; .$trenner;&lt;br /&gt;
    $mailheader .= &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    // Mailbody vorbereiten&lt;br /&gt;
    $mailbody  = &amp;quot;This is a multi-part message in MIME format\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;--&amp;quot; .$trenner. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Type: text/html; charset=UTF-8\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Transfer-Encoding: 8bit\r\n\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= $template. &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    // Anhang anfügen&lt;br /&gt;
    $mailbody .= &amp;quot;--&amp;quot; .$trenner. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Type: image/jpeg; name=\&amp;quot;&amp;quot; .$uploadname. &amp;quot;\&amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Transfer-Encoding: base64\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Disposition: attachment; filename=\&amp;quot;&amp;quot; .$uploadname. &amp;quot;\&amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= chunk_split( base64_encode( file_get_contents( $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;tmp_name&amp;#039;] ) ) );&lt;br /&gt;
    $mailbody .= &amp;quot;\n&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    // Email versenden&lt;br /&gt;
    if (@mail( $empfaenger, htmlspecialchars( $betreff ), $mailbody, $mailheader ))&lt;br /&gt;
    {&lt;br /&gt;
        // Bei erfolgreichem Versand Danke-Seite anzeigen&lt;br /&gt;
        echo &amp;#039;Danke, die Email wurde verschickt!&amp;#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen auf den ersten Blick, dass dieser Code ganz anders aussieht als das vorherige Beispiel. Gehen wir den Code mal der Reihe nach durch, um etwas Licht in&amp;#039;s Dunkel zu bringen.&lt;br /&gt;
&lt;br /&gt;
Im oberen Bereich erzeugen wir einen eindeutigen String, den wir zum trennen der verschiedenen Teilbereiche der Mail verwenden werden:&lt;br /&gt;
&lt;br /&gt;
 $trenner = md5( time() );&lt;br /&gt;
&lt;br /&gt;
Der erste Teil des Mail Header ist uns bereits bekannt, aber beim Content-Type benötigen wir nun eine andere Angabe.&lt;br /&gt;
&lt;br /&gt;
 $mailheader .= &amp;quot;Content-Type: multipart/mixed;\r\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
Dieser Content-Type ähnelt der Angabe &amp;quot;multipart/form-data&amp;quot; in einem HTML Formular, wenn wir dort ebenfalls gemischte Inhalte haben, nämlich Text und Dateien. Damit der Mail Client nun weiß an welchen Stellen im gesendeten Quellcode er Inhalte trennen muß, teilen wir im Header den boundary-String mit.&lt;br /&gt;
&lt;br /&gt;
An dieser Stelle möchte ich noch auf 2 wichtige Dinge hinweisen. Das Leerzeichen vor dem &amp;quot;boundary&amp;quot; im Header ist kein Versehen! Es kann tatsächlich dazu führen das eine Mail nicht korrekt dargestellt wird, wenn dieses Leerzeichen fehlt. Ebenso ist es wichtig, dass die &amp;quot;From&amp;quot;-Angabe unmittelbar vor der &amp;quot;MIME-Version&amp;quot; und dem &amp;quot;Content-Type&amp;quot; steht. Vertauscht man die Reihenfolge der Header Angabe, führt das z.B. bei mir dazu, dass ich im Thunderbird nur eine leere Seite als Mail angezeigt bekomme, obwohl der komplette Mail Inhalt im Quelltext einsehbar ist.&lt;br /&gt;
&lt;br /&gt;
Die nächste Zeile ...&lt;br /&gt;
&lt;br /&gt;
 $mailbody  = &amp;quot;This is a multi-part message in MIME format\r\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
... steht vor der Nachricht im Head Bereich in der Email. Sie scheint nicht zwingend erforderlich zu sein, aber Mail Clients fügen diese ebenfalls hinzu, wenn man mit z.B. Thunderbird eine Email verschickt. Ich vermute, dass dies aus Gründen der Kompatibilität zu einigen Mail Server geschieht.&lt;br /&gt;
&lt;br /&gt;
Nun folgt der erste Teil unserer Email, der Text.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    $mailbody .= &amp;quot;--&amp;quot; .$trenner. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Type: text/html; charset=UTF-8\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Transfer-Encoding: 8bit\r\n\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= $template. &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Durch den Trenner teilen wir dem Mail Client mit, dass zwischen diesem Trenner und dem nächsten Trenner, bzw. dem Ende der Mail, ein Teilabschnitt dieser Email steht. Damit der Client weiß um was es sich bei diesem Abschnitt handelt, teilen wir ihm das mithilfe des &amp;quot;Content-Type&amp;quot; und dem &amp;quot;Transfer-Encoding&amp;quot; mit. Durch die Angabe &amp;quot;text/html&amp;quot; weiß nun der Client, dass alles bis zum nächsten Trennen als HTML dargestellt werden soll.&lt;br /&gt;
&lt;br /&gt;
Der nächste Teilabschnitt der Mail ist unser Bild:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // Anhang anfügen&lt;br /&gt;
    $mailbody .= &amp;quot;--&amp;quot; .$trenner. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Type: image/jpeg; name=\&amp;quot;&amp;quot; .$uploadname. &amp;quot;\&amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Transfer-Encoding: base64\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Disposition: attachment; filename=\&amp;quot;&amp;quot; .$uploadname. &amp;quot;\&amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= chunk_split( base64_encode( file_get_contents( $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;tmp_name&amp;#039;] ) ) );&lt;br /&gt;
    $mailbody .= &amp;quot;\n&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wieder folgt zunächst der Trenner. Der Client stoppt seine HTML Ausgabe an dieser Position und wird ab diesem Punkt ausgeben, was ihm durch den &amp;quot;Content-Type&amp;quot; und das &amp;quot;Transfer-Encoding&amp;quot; aufgetragen wird. Wir sehen nun, dass wir als Content-Type eine JPG Datei ausgeben möchten. Der Name ergibt sich aus dem Rückgabewert der Funktion, die den Upload zuvor überprüft hat. Als Transfer-Encoding wird &amp;quot;base64&amp;quot; angegeben. Diese Angabe ist überaus wichtig um eine korrekte Übertragung der Daten zu gewährleisten. Mit der Angabe &amp;quot;Content-Disposition: attachment;&amp;quot; legen wir fest, dass der Anhang wirklich an die Mail angehängt wird. Eine andere Möglichkeit wäre hier das Einbetten in den Mailtext, indem man als Content-Disposition ein &amp;quot;inline&amp;quot; angibt. Die nächste Zeile ist ziemlich tricky:&lt;br /&gt;
&lt;br /&gt;
 $mailbody .= chunk_split( base64_encode( file_get_contents( $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;tmp_name&amp;#039;] ) ) );&lt;br /&gt;
&lt;br /&gt;
Arbeiten wir uns mal von Innen nach Außen durch, weil hier mehrere Funktionen verschachtelt sind. Mit file_get_contents wird eine Datei als String eingelesen. Dies ist hier möglich, weil diese Funktion seit PHP 4.3 binary safe ist. Als einzulesender Dateiname nehmen wir hier den Name der temporären datei, die durch den Upload auf dem Server gelandet ist. Diese Datei steht nur zu genau diesem Zeitpunkt zur Verfügung. Sobald das Script beendet wird oder eine andere Seite geladen wird, existiert diese Datei nicht mehr. Möchte man diese Datei erst zu einem späteren Zeitpunkt verarbeiten, muß man diese zunächst mit move_uploaded_file an eine andere Position kopieren.&lt;br /&gt;
Da wir nun die Bilddatei als String eingelesen haben, wird er mit base64_encode umgewandelt, damit die Datei beschädigt wird, falls es nicht möglich ist die Mail als 8bit zu übertragen. Es wird also aus Gründen der Kompatibilität gemacht. Anschließend wird der String mit chunk_split so aufbereitet, dass die Zeilenlänge 76 Zeichen nicht übersteigt.&lt;br /&gt;
&lt;br /&gt;
Das war&amp;#039;s! Die Daten können nun wieder mit der mail-Funktion versendet werden. Sollte man mehr als eine Datei anhängen wollen, kann man den letzten Schritt beliebig oft wiederholen. Erst Trenner setzen, dann Art der Daten und Übertragungsmodus angeben, die Datei anhängen, fertig.&lt;/div&gt;</summary>
		<author><name>178.7.132.100</name></author>
	</entry>
	<entry>
		<id>https://wiki.stephanschlegel.de/index.php?title=PHP_-_E-Mail_versenden&amp;diff=19045</id>
		<title>PHP - E-Mail versenden</title>
		<link rel="alternate" type="text/html" href="https://wiki.stephanschlegel.de/index.php?title=PHP_-_E-Mail_versenden&amp;diff=19045"/>
		<updated>2012-03-13T10:32:32Z</updated>

		<summary type="html">&lt;p&gt;178.7.132.100: Die Seite wurde neu angelegt: „Links  http://www.phpbuddy.eu/emails-mit-php-versenden.html?start=4    Todo Quelle siehe oben  Emails mit PHP versenden - HTML Email mit Anhang Beitragsseiten Ema…“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Links&lt;br /&gt;
&lt;br /&gt;
http://www.phpbuddy.eu/emails-mit-php-versenden.html?start=4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Todo Quelle siehe oben&lt;br /&gt;
&lt;br /&gt;
Emails mit PHP versenden - HTML Email mit Anhang&lt;br /&gt;
Beitragsseiten&lt;br /&gt;
Emails mit PHP versenden&lt;br /&gt;
Gemeinsam benutzte Funktionen&lt;br /&gt;
Einfache Text Email&lt;br /&gt;
HTML Email mit CSS Formatierung&lt;br /&gt;
HTML Email mit Anhang&lt;br /&gt;
Empfangsbestätigung an Absender&lt;br /&gt;
Alle Seiten&lt;br /&gt;
Seite 5 von 6&lt;br /&gt;
HTML Email mit CSS Formatierung und Dateianhang&lt;br /&gt;
&lt;br /&gt;
Da wir eine Datei mit der Mail verschicken möchten, muß das Formular natürlich dahingehend erweitert werden, dass ein Upload auch möglich ist. In unserem Beispiel möchten wir eine JPG datei anhängen und erlauben auch nur das hochladen dieses Bildtyps.&lt;br /&gt;
Die Template Datei ist identisch zum vorherigen HTML Beispiel. In der Datei funktionen.inc.php fügen wir aber eine weitere Funktion hinzu, die für uns prüft, ob eine Datei hochgeladen wurde und ob es sich dabei um eine JPG Datei handelt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function checkFile()&lt;br /&gt;
{&lt;br /&gt;
    if ($_FILES[&amp;#039;datei&amp;#039;][&amp;#039;error&amp;#039;] == 0 &amp;amp;&amp;amp;&lt;br /&gt;
        $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;type&amp;#039;] == &amp;#039;image/jpeg&amp;#039;)&lt;br /&gt;
    {&lt;br /&gt;
        return $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;name&amp;#039;];&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        die( &amp;#039;Bitte eine gültige JPG Datei anhängen!&amp;#039; );&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der Datei mail.php wird sich nun einiges ändern. Zunächst erweitern wir die einleitende Abfrage dahingehend, dass wir feststellen ob auch eine Datei angehängt wurde ...&lt;br /&gt;
&lt;br /&gt;
 if (isset($_POST[&amp;#039;senden&amp;#039;]) &amp;amp;&amp;amp; $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;size&amp;#039;] &amp;gt; 0)&lt;br /&gt;
&lt;br /&gt;
... und fügen ebenso den Aufruf für die neue Funktion hinzu, die prüft ob ein JPG hochgeladen wurde:&lt;br /&gt;
&lt;br /&gt;
 $uploadname = checkFile();&lt;br /&gt;
&lt;br /&gt;
Das weitere Listing der Datei mail.php sieht wie folgt aus:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // Template mit dem Mailbody laden&lt;br /&gt;
    $template = file_get_contents( &amp;#039;mailbody.txt&amp;#039; );&lt;br /&gt;
    // Trenner für den Anhang&lt;br /&gt;
    $trenner = md5( time() );&lt;br /&gt;
 &lt;br /&gt;
    // Platzhalter mit den Benutzereingaben ersetzen&lt;br /&gt;
    $template = str_replace( &amp;#039;###NAME###&amp;#039;, htmlspecialchars( $name ), $template );&lt;br /&gt;
    $template = str_replace( &amp;#039;###EMAIL###&amp;#039;, $email, $template );&lt;br /&gt;
    $template = str_replace( &amp;#039;###NACHRICHT###&amp;#039;, nl2br( htmlspecialchars( $nachricht ) ), $template );&lt;br /&gt;
 &lt;br /&gt;
    // Mail Header erstellen&lt;br /&gt;
    $mailheader .= &amp;quot;Reply-To: &amp;quot; .$name. &amp;quot;&amp;lt;&amp;quot; .$email. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Return-Path: noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Message-ID: &amp;lt;&amp;quot; .time(). &amp;quot; noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;X-Mailer: PHP v&amp;quot; .phpversion(). &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;From: PHP Email Tutorial&amp;lt;noreply@&amp;quot; .$_SERVER[&amp;#039;SERVER_NAME&amp;#039;]. &amp;quot;&amp;gt;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;MIME-Version: 1.0\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot;Content-Type: multipart/mixed;\r\n&amp;quot;;&lt;br /&gt;
    $mailheader .= &amp;quot; boundary = &amp;quot; .$trenner;&lt;br /&gt;
    $mailheader .= &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    // Mailbody vorbereiten&lt;br /&gt;
    $mailbody  = &amp;quot;This is a multi-part message in MIME format\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;--&amp;quot; .$trenner. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Type: text/html; charset=UTF-8\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Transfer-Encoding: 8bit\r\n\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= $template. &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    // Anhang anfügen&lt;br /&gt;
    $mailbody .= &amp;quot;--&amp;quot; .$trenner. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Type: image/jpeg; name=\&amp;quot;&amp;quot; .$uploadname. &amp;quot;\&amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Transfer-Encoding: base64\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Disposition: attachment; filename=\&amp;quot;&amp;quot; .$uploadname. &amp;quot;\&amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= chunk_split( base64_encode( file_get_contents( $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;tmp_name&amp;#039;] ) ) );&lt;br /&gt;
    $mailbody .= &amp;quot;\n&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    // Email versenden&lt;br /&gt;
    if (@mail( $empfaenger, htmlspecialchars( $betreff ), $mailbody, $mailheader ))&lt;br /&gt;
    {&lt;br /&gt;
        // Bei erfolgreichem Versand Danke-Seite anzeigen&lt;br /&gt;
        echo &amp;#039;Danke, die Email wurde verschickt!&amp;#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen auf den ersten Blick, dass dieser Code ganz anders aussieht als das vorherige Beispiel. Gehen wir den Code mal der Reihe nach durch, um etwas Licht in&amp;#039;s Dunkel zu bringen.&lt;br /&gt;
&lt;br /&gt;
Im oberen Bereich erzeugen wir einen eindeutigen String, den wir zum trennen der verschiedenen Teilbereiche der Mail verwenden werden:&lt;br /&gt;
&lt;br /&gt;
 $trenner = md5( time() );&lt;br /&gt;
&lt;br /&gt;
Der erste Teil des Mail Header ist uns bereits bekannt, aber beim Content-Type benötigen wir nun eine andere Angabe.&lt;br /&gt;
&lt;br /&gt;
 $mailheader .= &amp;quot;Content-Type: multipart/mixed;\r\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
Dieser Content-Type ähnelt der Angabe &amp;quot;multipart/form-data&amp;quot; in einem HTML Formular, wenn wir dort ebenfalls gemischte Inhalte haben, nämlich Text und Dateien. Damit der Mail Client nun weiß an welchen Stellen im gesendeten Quellcode er Inhalte trennen muß, teilen wir im Header den boundary-String mit.&lt;br /&gt;
&lt;br /&gt;
An dieser Stelle möchte ich noch auf 2 wichtige Dinge hinweisen. Das Leerzeichen vor dem &amp;quot;boundary&amp;quot; im Header ist kein Versehen! Es kann tatsächlich dazu führen das eine Mail nicht korrekt dargestellt wird, wenn dieses Leerzeichen fehlt. Ebenso ist es wichtig, dass die &amp;quot;From&amp;quot;-Angabe unmittelbar vor der &amp;quot;MIME-Version&amp;quot; und dem &amp;quot;Content-Type&amp;quot; steht. Vertauscht man die Reihenfolge der Header Angabe, führt das z.B. bei mir dazu, dass ich im Thunderbird nur eine leere Seite als Mail angezeigt bekomme, obwohl der komplette Mail Inhalt im Quelltext einsehbar ist.&lt;br /&gt;
&lt;br /&gt;
Die nächste Zeile ...&lt;br /&gt;
&lt;br /&gt;
 $mailbody  = &amp;quot;This is a multi-part message in MIME format\r\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
... steht vor der Nachricht im Head Bereich in der Email. Sie scheint nicht zwingend erforderlich zu sein, aber Mail Clients fügen diese ebenfalls hinzu, wenn man mit z.B. Thunderbird eine Email verschickt. Ich vermute, dass dies aus Gründen der Kompatibilität zu einigen Mail Server geschieht.&lt;br /&gt;
&lt;br /&gt;
Nun folgt der erste Teil unserer Email, der Text.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    $mailbody .= &amp;quot;--&amp;quot; .$trenner. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Type: text/html; charset=UTF-8\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Transfer-Encoding: 8bit\r\n\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= $template. &amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Durch den Trenner teilen wir dem Mail Client mit, dass zwischen diesem Trenner und dem nächsten Trenner, bzw. dem Ende der Mail, ein Teilabschnitt dieser Email steht. Damit der Client weiß um was es sich bei diesem Abschnitt handelt, teilen wir ihm das mithilfe des &amp;quot;Content-Type&amp;quot; und dem &amp;quot;Transfer-Encoding&amp;quot; mit. Durch die Angabe &amp;quot;text/html&amp;quot; weiß nun der Client, dass alles bis zum nächsten Trennen als HTML dargestellt werden soll.&lt;br /&gt;
&lt;br /&gt;
Der nächste Teilabschnitt der Mail ist unser Bild:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // Anhang anfügen&lt;br /&gt;
    $mailbody .= &amp;quot;--&amp;quot; .$trenner. &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Type: image/jpeg; name=\&amp;quot;&amp;quot; .$uploadname. &amp;quot;\&amp;quot;\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Transfer-Encoding: base64\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= &amp;quot;Content-Disposition: attachment; filename=\&amp;quot;&amp;quot; .$uploadname. &amp;quot;\&amp;quot;\r\n\r\n&amp;quot;;&lt;br /&gt;
    $mailbody .= chunk_split( base64_encode( file_get_contents( $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;tmp_name&amp;#039;] ) ) );&lt;br /&gt;
    $mailbody .= &amp;quot;\n&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wieder folgt zunächst der Trenner. Der Client stoppt seine HTML Ausgabe an dieser Position und wird ab diesem Punkt ausgeben, was ihm durch den &amp;quot;Content-Type&amp;quot; und das &amp;quot;Transfer-Encoding&amp;quot; aufgetragen wird. Wir sehen nun, dass wir als Content-Type eine JPG Datei ausgeben möchten. Der Name ergibt sich aus dem Rückgabewert der Funktion, die den Upload zuvor überprüft hat. Als Transfer-Encoding wird &amp;quot;base64&amp;quot; angegeben. Diese Angabe ist überaus wichtig um eine korrekte Übertragung der Daten zu gewährleisten. Mit der Angabe &amp;quot;Content-Disposition: attachment;&amp;quot; legen wir fest, dass der Anhang wirklich an die Mail angehängt wird. Eine andere Möglichkeit wäre hier das Einbetten in den Mailtext, indem man als Content-Disposition ein &amp;quot;inline&amp;quot; angibt. Die nächste Zeile ist ziemlich tricky:&lt;br /&gt;
&lt;br /&gt;
 $mailbody .= chunk_split( base64_encode( file_get_contents( $_FILES[&amp;#039;datei&amp;#039;][&amp;#039;tmp_name&amp;#039;] ) ) );&lt;br /&gt;
&lt;br /&gt;
Arbeiten wir uns mal von Innen nach Außen durch, weil hier mehrere Funktionen verschachtelt sind. Mit file_get_contents wird eine Datei als String eingelesen. Dies ist hier möglich, weil diese Funktion seit PHP 4.3 binary safe ist. Als einzulesender Dateiname nehmen wir hier den Name der temporären datei, die durch den Upload auf dem Server gelandet ist. Diese Datei steht nur zu genau diesem Zeitpunkt zur Verfügung. Sobald das Script beendet wird oder eine andere Seite geladen wird, existiert diese Datei nicht mehr. Möchte man diese Datei erst zu einem späteren Zeitpunkt verarbeiten, muß man diese zunächst mit move_uploaded_file an eine andere Position kopieren.&lt;br /&gt;
Da wir nun die Bilddatei als String eingelesen haben, wird er mit base64_encode umgewandelt, damit die Datei beschädigt wird, falls es nicht möglich ist die Mail als 8bit zu übertragen. Es wird also aus Gründen der Kompatibilität gemacht. Anschließend wird der String mit chunk_split so aufbereitet, dass die Zeilenlänge 76 Zeichen nicht übersteigt.&lt;br /&gt;
&lt;br /&gt;
Das war&amp;#039;s! Die Daten können nun wieder mit der mail-Funktion versendet werden. Sollte man mehr als eine Datei anhängen wollen, kann man den letzten Schritt beliebig oft wiederholen. Erst Trenner setzen, dann Art der Daten und Übertragungsmodus angeben, die Datei anhängen, fertig.&lt;/div&gt;</summary>
		<author><name>178.7.132.100</name></author>
	</entry>
	<entry>
		<id>https://wiki.stephanschlegel.de/index.php?title=PHP_-_Tipps_und_Tricks&amp;diff=19044</id>
		<title>PHP - Tipps und Tricks</title>
		<link rel="alternate" type="text/html" href="https://wiki.stephanschlegel.de/index.php?title=PHP_-_Tipps_und_Tricks&amp;diff=19044"/>
		<updated>2012-03-13T10:30:00Z</updated>

		<summary type="html">&lt;p&gt;178.7.132.100: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Mails mit php versenden ==&lt;br /&gt;
[[PHP - E-Mail versenden]]&lt;br /&gt;
&lt;br /&gt;
== Bilder schützen und nur über php ausliefern ==&lt;br /&gt;
1a Schutz per htaccess, so daß nur Zugriffe vom eigenen Server zulässig sind.&lt;br /&gt;
1b. Verzeichnisrechte so setzen, daß nur php-Nutzer lesen kann (oder einfach ein schwer zu erratender Verzeichnisname) -&amp;gt; kann man aber z.B. mit iFrame umgehen ist also weniger als Schutz praktisch, reicht aber, wenn man zur Laufzeit eine andere Variante des Bildes liefern will.&lt;br /&gt;
2. PHP Skript liefert die Bilder -&amp;gt; hier kann man dann User Access, Zeitsteuerung etc. regeln.&lt;br /&gt;
&lt;br /&gt;
Beispiel htaccess:&lt;br /&gt;
&lt;br /&gt;
Zugriff auf das Verzeichnis nur über php nicht über direktzugriff &lt;br /&gt;
&lt;br /&gt;
 order deny,allow&lt;br /&gt;
 deny  from all&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hierbei sind auf Bilder nur Zugriffe von der eigenen Domain erlaubt, ansonsten kommt ein Ersatzbild. Eignet sich z.B. um Traffic durch Bilderklau vorzubeugen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RewriteEngine on&lt;br /&gt;
RewriteCond %{HTTP_REFERER} !^$&lt;br /&gt;
RewriteCond %{HTTP_REFERER} !^http://(www.)?mydomain.de(/.*)?$ [NC]&lt;br /&gt;
RewriteRule .(gif|jpg|GIF|JPG)$ http://www.myDomain.de/images/ersatz.gif [R,L]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if ($_SESSION[&amp;#039;eingeloggt&amp;#039;] == true) {&lt;br /&gt;
   header(&amp;#039;Content-Type: image/jpeg&amp;#039;);&lt;br /&gt;
   readfile(&amp;#039;bild.jpg&amp;#039;);&lt;br /&gt;
} else {&lt;br /&gt;
   echo &amp;#039;Kein Direktzugriff erlaubt&amp;#039;; &lt;br /&gt;
}&lt;br /&gt;
?&amp;gt; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Weitere Beispiele mit htaccess:&lt;br /&gt;
&lt;br /&gt;
Beispiel mit Ersatzgrafik und mehreren URL&amp;#039;s:&lt;br /&gt;
Kann ja sein, dass man mehrere Homepages hat, die darauf zurückgreifen dürfen. Folgendes überträgst Du ins Notepad und speicherst es als .htaccess ab:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     RewriteEngine on&lt;br /&gt;
     RewriteCond %{HTTP_REFERER} !^$&lt;br /&gt;
     RewriteCond %{HTTP_REFERER} !^http://(www.)?webmaster-eye.de(/.*)?$ [NC]&lt;br /&gt;
     RewriteCond %{HTTP_REFERER} !^http://(www.)?mynickpage.de(/.*)?$ [NC]&lt;br /&gt;
     RewriteRule .(gif|jpg|GIF|JPG)$ http://www.webmaster-eye.de/images/ersatz.gif [R,L]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beispiel mit dem roten X:&lt;br /&gt;
Folgendes überträgst Du ins Notepad und speicherst es als .htaccess ab:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     RewriteEngine on&lt;br /&gt;
     RewriteCond %{HTTP_REFERER} !^$&lt;br /&gt;
     RewriteCond %{HTTP_REFERER} !^http://(www.)?webmaster-eye.de(/.*)?$ [NC]&lt;br /&gt;
     RewriteRule .(gif|jpg)$ - [F]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quelle der htaccess Beispiele: http://www.webmaster-eye.de/Traffic-sparen-mit-htaccess-als-Bilder-Schutz.242.artikel.html (11/2011)&lt;br /&gt;
&lt;br /&gt;
== Weiterleitung mit PHP ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 header(&amp;quot;Location: http://www.myHomepage.net&amp;quot;);&lt;br /&gt;
 exit;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Ausgaben zwischenspeichern oder in Variablen umleiten ==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Problem: Die Ausgabe von echo oder von includes soll zuerst in einer Variablen gespeichert werden, damit Sie nicht gleich ausgegeben werden.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 &lt;br /&gt;
Das läßt sich lösen indem man die Ausgabe zunächst puffert und dann den Puffer in eine Variable lädt.&lt;br /&gt;
 basicartsstudios at hotmail dot com&lt;br /&gt;
21-Jan-2007 10:39&lt;br /&gt;
Sometimes you might not want to include a php-file under the specifications defined in the functions include() or require(), but you might want to have in return the string that the script in the file &amp;quot;echoes&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Include() and require() both directly put out the evaluated code.&lt;br /&gt;
&lt;br /&gt;
For avoiding this, try output-buffering:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
ob_start();&lt;br /&gt;
eval(file_get_contents($file));&lt;br /&gt;
$result = ob_get_contents();&lt;br /&gt;
ob_end_clean();&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
ob_start();&lt;br /&gt;
include($file);&lt;br /&gt;
$result = ob_get_contents();&lt;br /&gt;
ob_end_clean();&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which i consider the same, correct me if I&amp;#039;m wrong.&lt;br /&gt;
&lt;br /&gt;
Best regards, BasicArtsStudios&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Umlaute, UTF-8 und PHP: wenn Sonderzeichen falsch dargestellt werden ==&lt;br /&gt;
Quelle: http://www.sjmfreelancing.de/devblog/umlaute-utf-8-und-php.html (15.10.2008)&lt;br /&gt;
&lt;br /&gt;
Ich habe des öfteren das Problem gehabt, dass Sonderzeichen auf PHP-basierten Internetseiten nicht korrekt angezeigt wurden und Firefox ein gerahmtes Fragezeichen statt Ü, ü etc. ausgab, der Internet Explorer einen Kasten und auch Safari&amp;amp;Co. Probleme hatten.&lt;br /&gt;
&lt;br /&gt;
Lange war ich auf der Suche nach der richtigen Lösung für dieses Problem und habe mich durch unterschiedliche Blogs, Foren und Internetseiten gewühlt bis ich letztendlich eine Ansammlung verschiedenster Tipps &amp;amp; Tricks aufgenommen und in Kombination angewandt habe. Und siehe da: Sonderzeichen sind korrekt :)&lt;br /&gt;
&lt;br /&gt;
Hier ein paar Dinge, die jeder Programmierer beherzigen sollte, wenn er mit Umlauten umgeht:&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1. Header korrekt setzen&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Mit einem Einzeiler kann man PHP dazu bringen einen UTF-8-Header an den Browser zu senden. Einfach folgenden Code ganz oben in der Index-Datei setzen:&lt;br /&gt;
&lt;br /&gt;
 header(&amp;#039;content-type: text/html; charset=UTF-8&amp;#039;);  &lt;br /&gt;
&lt;br /&gt;
2. HTML-Header korrekt setzen&lt;br /&gt;
&lt;br /&gt;
Folgenden Code in den HEAD-Bereich des HTML-Dokuments setzen:&lt;br /&gt;
view plaincopy to clipboardprint?&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=UTF-8&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. PHP-Dateien im UTF-8-Format speichern&lt;br /&gt;
&lt;br /&gt;
Ganz wichtig ist es die PHP-Dateien die man verwendet im UTF-8-Format zu speichern. Sprich: den Editor dazu zu bringen, die Datei mit Umlauten zu speichern.&lt;br /&gt;
4. MySQL dazu bewegen UTF-8 zu nutzen&lt;br /&gt;
&lt;br /&gt;
MySQL liefert auch nicht (immer) von Haus aus UTF-8-korrekte Ausgaben. Folgendes MySQL-Query einfach nach dem connecten mit der Datenbank ausführen:&lt;br /&gt;
&lt;br /&gt;
 mysql_query(&amp;#039;set character set utf8;&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
5. Das &amp;amp;-Zeichen immer escapen&lt;br /&gt;
&lt;br /&gt;
Zwar nicht direkt ein Problem, aber: ü, ä, ß etc. sind auch dann korrektes HTML, wenn man sie nicht mittels htmlentities in Entitäten umgewandelt hat. Anders sieht es mit dem Kaufmanns-Und (&amp;amp;) aus: diesen IMMER mit &amp;amp;amp; ausgeben. Auch bei Links gilt: &amp;amp; durch &amp;lt;code&amp;gt;&amp;amp;amp;&amp;lt;/code&amp;gt; ersetzen!&lt;br /&gt;
&lt;br /&gt;
== Validieren von Werten aus Eingabefeldern ==&lt;br /&gt;
[[PHP - Validierung von Werten aus Eingabefeldern]]&lt;br /&gt;
&lt;br /&gt;
== Sicherheit in PHP Skripts ==&lt;/div&gt;</summary>
		<author><name>178.7.132.100</name></author>
	</entry>
	<entry>
		<id>https://wiki.stephanschlegel.de/index.php?title=Typo3_-_Mehrsprachige_Seiten&amp;diff=19026</id>
		<title>Typo3 - Mehrsprachige Seiten</title>
		<link rel="alternate" type="text/html" href="https://wiki.stephanschlegel.de/index.php?title=Typo3_-_Mehrsprachige_Seiten&amp;diff=19026"/>
		<updated>2012-03-07T18:20:44Z</updated>

		<summary type="html">&lt;p&gt;178.7.132.100: /* Quickstart */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Siehe auch: [[Typo3 - Standardeinstellungen]]&lt;br /&gt;
&lt;br /&gt;
== Quickstart ==&lt;br /&gt;
=== One Tree Multilanguage Basic TS ===&lt;br /&gt;
Default Sprache wäre hier en (uid = 0)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
config{&lt;br /&gt;
	// more properties for multilanguage pages&lt;br /&gt;
	linkVars = L(1-10)&lt;br /&gt;
	uniqueLinkVars = 1&lt;br /&gt;
	sys_language_mode = content_fallback&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
	// Language Settings for second language&lt;br /&gt;
&lt;br /&gt;
[globalVar = GP:L=1]&lt;br /&gt;
config {&lt;br /&gt;
	language = de&lt;br /&gt;
	locale_all = de_DE&lt;br /&gt;
	htmlTag_langKey = de&lt;br /&gt;
	sys_language_uid = 1&lt;br /&gt;
}&lt;br /&gt;
[global]&lt;br /&gt;
[globalVar = GP:L=2]&lt;br /&gt;
config {&lt;br /&gt;
	language = es&lt;br /&gt;
	locale_all = es_ES&lt;br /&gt;
	htmlTag_langKey = es&lt;br /&gt;
	sys_language_uid = 2&lt;br /&gt;
}&lt;br /&gt;
[global]&lt;br /&gt;
[globalVar = GP:L=3]&lt;br /&gt;
config {&lt;br /&gt;
	language = fr&lt;br /&gt;
	locale_all = fr_FR&lt;br /&gt;
	htmlTag_langKey = fr&lt;br /&gt;
	sys_language_uid = 3&lt;br /&gt;
}&lt;br /&gt;
[global]&lt;br /&gt;
[globalVar = GP:L=4]&lt;br /&gt;
config {&lt;br /&gt;
	language = it&lt;br /&gt;
	locale_all = it_IT&lt;br /&gt;
	htmlTag_langKey = it&lt;br /&gt;
	sys_language_uid = 4&lt;br /&gt;
}&lt;br /&gt;
[global]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Sprachmenü Textversion ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
########################################&lt;br /&gt;
### Standard Sprachmenu (TS Version) ###&lt;br /&gt;
########################################&lt;br /&gt;
&lt;br /&gt;
temp.langTextMenu = COA&lt;br /&gt;
temp.langTextMenu{&lt;br /&gt;
  10 = TEXT&lt;br /&gt;
  10 {&lt;br /&gt;
    		# Labels&lt;br /&gt;
    		#value = Language:&lt;br /&gt;
    		#lang.de = Sprache:&lt;br /&gt;
    		#lang.fr = Langue:&lt;br /&gt;
    		#wrap = &amp;lt;div id=&amp;quot;nav-lang-label&amp;quot;&amp;gt;|&amp;lt;/div&amp;gt;&lt;br /&gt;
  }&lt;br /&gt;
  20 = HMENU&lt;br /&gt;
  20{&lt;br /&gt;
    wrap = &amp;lt;div id=&amp;quot;nav-lang&amp;quot;&amp;gt;|&amp;lt;/div&amp;gt;&lt;br /&gt;
    special = language&lt;br /&gt;
    		# Liste der Sprach IDs (0 = Deutsch, 1 = Englisch, 2 = Franzoesisch)&lt;br /&gt;
    		//special.value = 0,1,2&lt;br /&gt;
    special.value = 0,1&lt;br /&gt;
    1 = TMENU&lt;br /&gt;
    1{&lt;br /&gt;
      wrap = &amp;lt;ul class=&amp;quot;nav&amp;quot;&amp;gt;|&amp;lt;/ul&amp;gt;&lt;br /&gt;
      NO = 1&lt;br /&gt;
      NO {&lt;br /&gt;
        stdWrap.cObject = TEXT&lt;br /&gt;
        stdWrap.cObject{&lt;br /&gt;
          value = english || deutsch&lt;br /&gt;
          					# oder auf diese Weise:&lt;br /&gt;
          					#lang.de = Englisch || Deutsch || Franzoesich&lt;br /&gt;
          					#lang.fr = ...&lt;br /&gt;
        }&lt;br /&gt;
        allWrap = &amp;lt;li class = &amp;quot;no first&amp;quot;&amp;gt; | &amp;lt;/li&amp;gt;|*|&amp;lt;li class = &amp;quot;no&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;amp;#x007C;&amp;amp;nbsp; | &amp;lt;/li&amp;gt;|*|&amp;lt;li class = &amp;quot;no last&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;amp;#x007C;&amp;amp;nbsp; | &amp;lt;/li&amp;gt;&lt;br /&gt;
      }&lt;br /&gt;
      ACT &amp;lt; .NO&lt;br /&gt;
      ACT {&lt;br /&gt;
        doNotLinkIt = 1&lt;br /&gt;
        allWrap = &amp;lt;li class = &amp;quot;act first&amp;quot;&amp;gt; | &amp;lt;/li&amp;gt;|*|&amp;lt;li class = &amp;quot;act&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;amp;#x007C;&amp;amp;nbsp; | &amp;lt;/li&amp;gt;|*|&amp;lt;li class = &amp;quot;act last&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;amp;#x007C;&amp;amp;nbsp; | &amp;lt;/li&amp;gt;&lt;br /&gt;
      }&lt;br /&gt;
      			# Zustand NO wenn keine Uebersetzung vorliegt&lt;br /&gt;
      USERDEF1 &amp;lt; .NO&lt;br /&gt;
      USERDEF1 {&lt;br /&gt;
        doNotLinkIt = 1&lt;br /&gt;
        allWrap = &amp;lt;li class = &amp;quot;no empty first&amp;quot;&amp;gt; | &amp;lt;/li&amp;gt;|*|&amp;lt;li class = &amp;quot;no empty&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;amp;#x007C;&amp;amp;nbsp; | &amp;lt;/li&amp;gt;|*|&amp;lt;li class = &amp;quot;no empty last&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;amp;#x007C;&amp;amp;nbsp; | &amp;lt;/li&amp;gt;&lt;br /&gt;
      }&lt;br /&gt;
      			# Zustand ACT wenn keine Uebersetzung vorliegt&lt;br /&gt;
      USERDEF2 &amp;lt; .NO&lt;br /&gt;
      USERDEF2 {&lt;br /&gt;
        doNotLinkIt = 1&lt;br /&gt;
        allWrap = &amp;lt;li class=&amp;quot;act empty first&amp;quot;&amp;gt; | &amp;lt;/li&amp;gt;|*|&amp;lt;li class=&amp;quot;act empty&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;amp;#x007C;&amp;amp;nbsp; | &amp;lt;/li&amp;gt;|*|&amp;lt;li class=&amp;quot;act empty last&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;amp;#x007C;&amp;amp;nbsp; | &amp;lt;/li&amp;gt;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sprachmenü grafische Version ===&lt;br /&gt;
Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
1. obiges Menü anpassen&lt;br /&gt;
&lt;br /&gt;
2. siehe unten php Version&lt;br /&gt;
&lt;br /&gt;
3. sr_language_menu Extension&lt;br /&gt;
&lt;br /&gt;
siehe auch [[TYPO3 Sprachmenü mit sr_language_menu]]&lt;br /&gt;
&lt;br /&gt;
== Einführung ==&lt;br /&gt;
* HTML-Template: Marker einbinden &lt;br /&gt;
* TypoScript: Marker mit Sprachskript füllen (PHP-Objekt)&lt;br /&gt;
* Dateien: Notwendige Dateien hochspielen (Skript und Grafiken)&lt;br /&gt;
* CSS anpassen damit Flaggen schön aussehen&lt;br /&gt;
* Backend: Sprache anlegen (Weltkugel)&lt;br /&gt;
* Evt. Spracheinstellungen im TypoScript (das meiste im vorgefertigten Template)&lt;br /&gt;
Hinweis: alles im Baukasten (Common - Ordner) ToDo&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===2 Konzepte===&lt;br /&gt;
Um Mehrsprachigkeit zu realisieren gibt es zwei Ansätze:&lt;br /&gt;
# Multitree - Mehrere Navigationsbäume (für jede Sprache einen). In den Navigationsbäumen müssen die Templates entsprechend Variiert werden.&lt;br /&gt;
# One Tree Fits All - Mehrsprachigkeit mit den Typo3 Bordmitteln (der moderne Ansatz). Hierbei können im System mehrere Sprachen angelegt werden. Jede Sprache hat nachher in der Seitenansicht eine eigene Spalte. So hat man eine gute Übersicht welche Inhaltselemente bereits übersetzt sind.&lt;br /&gt;
&lt;br /&gt;
===Welcher Ansatz ist der Richtige ?===&lt;br /&gt;
Kommt drauf an. Wer soll damit klar kommen? Wieviele Seiten sind es? Werden alle Seiten übersetzt?&lt;br /&gt;
&lt;br /&gt;
===TypoScript Anpassungen===&lt;br /&gt;
Damit das System merkt in welcher Sprache es sich z.Zt. befindet wird der URL ein Parameter mitgegeben. Allgemein ist der Parameter L vereinbart. Das sollte auch eingehalten werden weil einige Extensions nur mit L als Variable arbeiten. &lt;br /&gt;
&lt;br /&gt;
Damit das ganze funktioniert müssen Anpassungen mit TypoScript gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ein Zusätzliches Basis Template anlegen. Für eine deutsch-englische Seite kann das Setup z.B. so aussehen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
### Parameter L definieren 0 soll die default Sprache (deutsch) sein ###&lt;br /&gt;
config.linkVars = L(0-2)&lt;br /&gt;
config.sys_language_uid = 0&lt;br /&gt;
config.language = de&lt;br /&gt;
config.locale_all = de_DE&lt;br /&gt;
#config.sys_language_mode = content_fallback;0 //sucht in default Sprache falls nichts vorhanden&lt;br /&gt;
#config.sys_language_mode = content_fallback : 1,0 // sucht in lang1 ansonsten in 0&lt;br /&gt;
config.sys_language_mode = strict&lt;br /&gt;
config.sys_language_overlay = hideNonTranslated&lt;br /&gt;
 &lt;br /&gt;
 # Testen ob die Englische Seite gewünscht wird. In einem CASE Konstrukt wird dazu geprüft&lt;br /&gt;
 # ob die globale Variable L=1 ist&lt;br /&gt;
 [globalVar = GP:L = 1]&lt;br /&gt;
    config.sys_language_uid = 1&lt;br /&gt;
    config.language = en&lt;br /&gt;
    config.locale_all = en_EN&lt;br /&gt;
 [global]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Erläuterung:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Im ersten Teil wird die globale Variable L definiert und dann Deutsch als default-Sprache festgelegt und mit L=0 gleichgesetzt. Danach wird getestet ob der Parameter L mit dem Wert 1 übergeben wird. Ist das der Fall wird die Systemsprache auf englisch gesetzt. Das führt später auch dazu, daß die Inhalte aus der Englischen Spalte ausgegeben werden.&lt;br /&gt;
&lt;br /&gt;
Jetzt fehlt noch ein Auswahlmenü mit dem sich die Sprache auf der Webseite auswählen läßt.&lt;br /&gt;
&lt;br /&gt;
===Sprachauswahlmenü programmieren===&lt;br /&gt;
In der Subpart definition (workOnSubparts) des Haupttemplates binden wir ein PHP-Skript ein, dass dafür sorgt, daß an der Stelle des Markers (hier LANGUAGE) das Menü eingebunden wird und das bei Klicks auf einen Link immer die richtige Nummer für die Sprache an die URL angehängt wird.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;TypoScript:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   #multilanguage-flags&lt;br /&gt;
   marks.LANGUAGE=TEXT&lt;br /&gt;
   marks.LANGUAGE=&amp;amp;nbsp;&lt;br /&gt;
   marks.LANGUAGE=PHP_SCRIPT&lt;br /&gt;
   marks.LANGUAGE.file=fileadmin/scripts/languageMenu_d-e.php&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;php-Skript:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
 /**&lt;br /&gt;
 * languageMenu_d-e.php basiert auf example_languageMenu.php &lt;br /&gt;
 *&lt;br /&gt;
 * @author	Kasper Skårhøj &amp;lt;kasper@typo3.com&amp;gt;&lt;br /&gt;
 * @modified by Stephan Schlegel www.geo-bit.de&lt;br /&gt;
 */&lt;br /&gt;
 // First, select all pages_language_overlay records on the current page. Each represents a possibility for a language.&lt;br /&gt;
 $query = &amp;quot;SELECT * FROM pages_language_overlay WHERE pid=&amp;quot;.$GLOBALS[&amp;quot;TSFE&amp;quot;]-&amp;gt;id.$GLOBALS[&amp;quot;TSFE&amp;quot;]-&amp;gt;sys_page-&amp;gt;enableFields(&amp;quot;pages_language_overlay&amp;quot;).&amp;quot; GROUP BY sys_language_uid&amp;quot;;&lt;br /&gt;
 $res = mysql(TYPO3_db,$query);&lt;br /&gt;
 $langArr=array();&lt;br /&gt;
 while($row=mysql_fetch_assoc($res))	{&lt;br /&gt;
 $langArr[$row[&amp;quot;sys_language_uid&amp;quot;]]=$row[&amp;quot;title&amp;quot;];&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // Little red arrow, which is inserted to the left of the flag-icon if the &lt;br /&gt;
 // TSFE-&amp;gt;sys_language_uid equals the language uid (notice that 0=deutsch, 1=englisch  &lt;br /&gt;
 // is SPECIFIC to this database, because these numbers refer to uid&amp;#039;s of the table sys_language)&lt;br /&gt;
 $pointer = &amp;#039;&amp;lt;img src=&amp;quot;fileadmin/scripts/pointer.gif&amp;quot; width=&amp;quot;7&amp;quot; height=&amp;quot;10&amp;quot; align=middle&amp;gt;&amp;#039;;&lt;br /&gt;
 // Set each icon. If the language is the current, red arrow is printed to the left. &lt;br /&gt;
 // If the language is NOT found (represented by a pages_language_overlay record on this page), the icon is dimmed.&lt;br /&gt;
 $flags = array();&lt;br /&gt;
 $flags[] = ($GLOBALS[&amp;quot;TSFE&amp;quot;]-&amp;gt;sys_language_uid==0?$pointer:&amp;quot;&amp;quot;).&amp;#039;&amp;lt;a href=&amp;quot;index.php?id=&amp;#039;.$GLOBALS[&amp;quot;TSFE&amp;quot;]-&amp;gt;id.&amp;#039;&amp;amp;L=0&amp;quot; target=_top&amp;gt;&amp;lt;img src=&amp;quot;media/uploads/flag_de.gif&amp;quot; alt=&amp;quot;deutsch&amp;quot; width=&amp;quot;21&amp;quot; height=&amp;quot;13&amp;quot; hspace=5 border=&amp;quot;0&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&amp;#039;;&lt;br /&gt;
 $flags[] = ($GLOBALS[&amp;quot;TSFE&amp;quot;]-&amp;gt;sys_language_uid==1?$pointer:&amp;quot;&amp;quot;).&amp;#039;&amp;lt;a href=&amp;quot;index.php?id=&amp;#039;.$GLOBALS[&amp;quot;TSFE&amp;quot;]-&amp;gt;id.&amp;#039;&amp;amp;L=1&amp;quot; target=_top&amp;gt;&amp;lt;img src=&amp;quot;media/uploads/flag_uk&amp;#039;.($langArr[1]?&amp;quot;&amp;quot;:&amp;quot;_d&amp;quot;).&amp;#039;.gif&amp;quot; alt=&amp;quot;english&amp;quot; width=&amp;quot;21&amp;quot; height=&amp;quot;13&amp;quot; hspace=5 border=&amp;quot;0&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 // Make the little menu. Notice, the menu does ONLY transfer the page-id and the &amp;quot;L&amp;quot; variable (which is also SPECIFIC for this website because &amp;quot;L&amp;quot; has been used in the extension template used to control the language setup)&lt;br /&gt;
 $content = &amp;#039;&amp;lt;span class=&amp;quot;language_selector&amp;quot;&amp;gt;&amp;#039;.implode(&amp;quot;&amp;quot;,$flags).&amp;#039;&amp;lt;/span&amp;gt;&amp;#039;;&lt;br /&gt;
 ?&amp;gt;&lt;br /&gt;
===Rootline für mehrere Sprachen einrichten===&lt;br /&gt;
 temp.rootline = HMENU&lt;br /&gt;
 temp.rootline.special = rootline&lt;br /&gt;
 temp.rootline.special.range = 0|-1&lt;br /&gt;
 temp.rootline.wrap = Sie sind hier:&lt;br /&gt;
 temp.rootline.1 = TMENU&lt;br /&gt;
 temp.rootline.1 {&lt;br /&gt;
    target = _top&lt;br /&gt;
    NO.linkWrap = || /&lt;br /&gt;
 }&lt;br /&gt;
 # evt. bestimte Seiten ausblenden...&lt;br /&gt;
 temp.rootline.excludeUidList =&lt;br /&gt;
 &lt;br /&gt;
 # Sprache mit der ID 3&lt;br /&gt;
 [globalVar = GP:L = 3]&lt;br /&gt;
    temp.rootline.wrap = You are here:&lt;br /&gt;
 [global]&lt;br /&gt;
 &lt;br /&gt;
 # Sprache mit der ID 4&lt;br /&gt;
 [globalVar = GP:L = 4]&lt;br /&gt;
    temp.rootline.wrap = bla bla:&lt;br /&gt;
 [global]&lt;br /&gt;
 &lt;br /&gt;
 # Sprache mit der ID X (X = beliebige zahl)&lt;br /&gt;
 [globalVar = GP:L = X]&lt;br /&gt;
    temp.rootline.wrap = hierher haben sie sich verirrt:&lt;br /&gt;
 [global]&lt;br /&gt;
&lt;br /&gt;
=== Ein Beispiel für ein vollständiges (zweisprachiges) TypoScript ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
### Spracheinstellungen ###&lt;br /&gt;
config.linkVars = L&lt;br /&gt;
config.sys_language_mode = content_fallback;0&lt;br /&gt;
&lt;br /&gt;
[globalVar = GP:L = 0]&lt;br /&gt;
config.sys_language_uid = 0&lt;br /&gt;
config.language = de&lt;br /&gt;
config.locale_all = de_DE&lt;br /&gt;
&lt;br /&gt;
# Link to top&lt;br /&gt;
#content.linkToTop &amp;gt;&lt;br /&gt;
tt_content.stdWrap.innerWrap2 = |&amp;lt;br&amp;gt;&amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;A href=&amp;quot;#top&amp;quot;&amp;gt;&amp;lt;font color=&amp;quot;#AB3C4B&amp;quot; face=&amp;quot;Arial, Helvetica, sans-serif&amp;quot; size=&amp;quot;1&amp;quot;&amp;gt;&amp;lt;B&amp;gt;nach oben&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#Suchfunktion&lt;br /&gt;
tt_content.search{&lt;br /&gt;
   20.layout.10.value = Suchergebnis: ###RANGELOW###-###RANGEHIGH### von ###TOTAL###&lt;br /&gt;
   20.noResultObj.10.value = Keine Treffer.&lt;br /&gt;
   20.next.value=nächste&lt;br /&gt;
   20.prev.value=vorherige&lt;br /&gt;
   30.dataArray.10.label = Suche nach:&lt;br /&gt;
   30.dataArray.20.label = Suche in:&lt;br /&gt;
   30.dataArray.20.valueArray.10.label = Überschriften und Schlüsselworten&lt;br /&gt;
   30.dataArray.20.valueArray.20.label = Seiteninhalten&lt;br /&gt;
   30.dataArray.40.value = Suche starten&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
[global]&lt;br /&gt;
&lt;br /&gt;
# English language, sys_language.uid = 1&lt;br /&gt;
[globalVar = GP:L = 1]&lt;br /&gt;
config.sys_language_uid = 1&lt;br /&gt;
config.language = en&lt;br /&gt;
config.locale_all = english&lt;br /&gt;
&lt;br /&gt;
#  Link to top&lt;br /&gt;
#content.linkToTop &amp;gt;&lt;br /&gt;
tt_content.stdWrap.innerWrap2 = &amp;lt;br&amp;gt;&amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;A href=&amp;quot;#top&amp;quot;&amp;gt;&amp;lt;font color=&amp;quot;#AB3C4B&amp;quot; face=&amp;quot;Arial, Helvetica, sans-serif&amp;quot; size=&amp;quot;1&amp;quot;&amp;gt;&amp;lt;B&amp;gt;to top&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#Suchfunktion - englisch&lt;br /&gt;
tt_content.search{&lt;br /&gt;
   20.layout.10.value = Suchergebnis: ###RANGELOW###-###RANGEHIGH### von ###TOTAL###&lt;br /&gt;
   20.noResultObj.10.value = No hits.&lt;br /&gt;
   20.next.value=next&lt;br /&gt;
   20.prev.value=previous&lt;br /&gt;
   30.dataArray.10.label = Searchwords:&lt;br /&gt;
   30.dataArray.20.label = Search in:&lt;br /&gt;
   30.dataArray.20.valueArray.10.label = Headlines &amp;amp; Keywords&lt;br /&gt;
   30.dataArray.20.valueArray.20.label = Content&lt;br /&gt;
   30.dataArray.40.value = Start search&lt;br /&gt;
}&lt;br /&gt;
[global]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Schritt für Schritt Anleitung ===&lt;br /&gt;
* Mindestens eine weitere Sprache anlegen (Listenansicht - Weltkugel)&lt;br /&gt;
* TypoScript Sprachvariable und Template anpassen:&lt;br /&gt;
* Benötigte Skripte und Bilder(Flaggen) Uploaden&amp;lt;br&amp;gt;z.B. mulitlan_d-e.php, flag_uk.gif...&lt;br /&gt;
* Marker im TypoScript Template anlegen:z.B.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
### Multilanguage-Navi ###&lt;br /&gt;
  marks.LANGUAGE=PHP_SCRIPT&lt;br /&gt;
  marks.LANGUAGE.file=fileadmin/scripts/languageMenu_e-d.php&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Marker im HTML-Template einbauen. Am besten in divs damit man es per CSS gestalten kann&lt;br /&gt;
 &amp;lt;div id=&amp;quot;languageSelector&amp;quot;&amp;gt;###LANGUAGE###&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Probleme bei mehrsprachigen Seiten ===&lt;br /&gt;
Lösungen bei verschiedenen Problemen mit mehrsprachigen Seiten gibt es hier:&lt;br /&gt;
&lt;br /&gt;
[[Typo3 - Probleme mit mehrsprachigen Seiten lösen]]&lt;br /&gt;
&lt;br /&gt;
=== Skriptsammlung ===&lt;br /&gt;
==== php-Sprachskript ====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
* languageMenu_d-e.php basiert auf example_languageMenu.php &lt;br /&gt;
*&lt;br /&gt;
* @author	Kasper Skårhøj &amp;lt;kasper@typo3.com&amp;gt;&lt;br /&gt;
* @modified by Stephan Schlegel www.geo-bit.de&lt;br /&gt;
*/&lt;br /&gt;
// First, select all pages_language_overlay records on the current page. &lt;br /&gt;
// Each represents a possibility for a language.&lt;br /&gt;
$query = &amp;quot;SELECT * FROM pages_language_overlay WHERE pid=&amp;quot;.$GLOBALS[&amp;quot;TSFE&amp;quot;]-&amp;gt;id.$GLOBALS[&amp;quot;TSFE&amp;quot;]-&amp;gt;sys_page-&amp;gt;enableFields(&amp;quot;pages_language_overlay&amp;quot;).&amp;quot; GROUP BY sys_language_uid&amp;quot;;&lt;br /&gt;
$res = mysql(TYPO3_db,$query);&lt;br /&gt;
$langArr=array();&lt;br /&gt;
while($row=mysql_fetch_assoc($res))	{&lt;br /&gt;
$langArr[$row[&amp;quot;sys_language_uid&amp;quot;]]=$row[&amp;quot;title&amp;quot;];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Little red arrow, which is inserted to the left of the flag-icon if the &lt;br /&gt;
// TSFE-&amp;gt;sys_language_uid equals the language uid (notice that 0=deutsch, 1=englisch  &lt;br /&gt;
// is SPECIFIC to this database, because these numbers refer to uid&amp;#039;s of the table sys_language)&lt;br /&gt;
//$pointer = &amp;#039;&amp;lt;img src=&amp;quot;fileadmin/scripts/pointer.gif&amp;quot; width=&amp;quot;7&amp;quot; height=&amp;quot;10&amp;quot; align=middle&amp;gt;&amp;#039;;&lt;br /&gt;
$pointer = &amp;quot;&amp;quot;;&lt;br /&gt;
// Set each icon. If the language is the current, red arrow is printed to the left. &lt;br /&gt;
// If the language is NOT found (represented by a pages_language_overlay record on this page), the icon is dimmed.&lt;br /&gt;
$flags = array();&lt;br /&gt;
$flags[] = &amp;#039;&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;index.php?id=&amp;#039;.$GLOBALS[&amp;quot;TSFE&amp;quot;]-&amp;gt;id.&amp;#039;&amp;amp;L=0&amp;quot; target=_top&amp;gt;&amp;lt;span class=&amp;quot;flag&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;fileadmin/template/images/flag_de.gif&amp;quot; alt=&amp;quot;deutsch&amp;quot; title=&amp;quot;deutsch&amp;quot; border=&amp;quot;0&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&amp;#039;;&lt;br /&gt;
$flags[] = &amp;#039;&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;index.php?id=&amp;#039;.$GLOBALS[&amp;quot;TSFE&amp;quot;]-&amp;gt;id.&amp;#039;&amp;amp;L=1&amp;quot; target=_top&amp;gt;&amp;lt;span class=&amp;quot;flag&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;fileadmin/template/images/flag_uk&amp;#039;.($langArr[1]?&amp;quot;&amp;quot;:&amp;quot;_d&amp;quot;).&amp;#039;.gif&amp;quot; alt=&amp;quot;english&amp;quot; title=&amp;quot;english&amp;quot; border=&amp;quot;0&amp;quot;&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
// Make the little menu. Notice, the menu does ONLY transfer the page-id and the &amp;quot;L&amp;quot; variable (which is also SPECIFIC for this website because &amp;quot;L&amp;quot; has been used in the extension template used to control the language setup)&lt;br /&gt;
$content = &amp;#039;&amp;lt;ul&amp;gt;&amp;#039;.implode(&amp;quot;&amp;quot;,$flags).&amp;#039;&amp;lt;/ul&amp;gt;&amp;#039;;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== TypoScript multilanguage Extension ====&lt;br /&gt;
ext_multilang_d-e.tmpl&lt;br /&gt;
&lt;br /&gt;
Setup:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
### Spracheinstellungen ###&lt;br /&gt;
config.linkVars = L&lt;br /&gt;
config.sys_language_mode = content_fallback;0&lt;br /&gt;
&lt;br /&gt;
### ohne Sprachauswahl ###&lt;br /&gt;
&lt;br /&gt;
# Standardsprache deutsch wird festgelegt &lt;br /&gt;
config.sys_language_uid = 0&lt;br /&gt;
config.language = de&lt;br /&gt;
config.locale_all = de_DE&lt;br /&gt;
&lt;br /&gt;
# CSS&lt;br /&gt;
page.stylesheet = fileadmin/template/css/main.css&lt;br /&gt;
&lt;br /&gt;
### DEUTSCH ###&lt;br /&gt;
[globalVar = GP:L = 0]&lt;br /&gt;
config.sys_language_uid = 0&lt;br /&gt;
config.language = de&lt;br /&gt;
config.locale_all = de_DE&lt;br /&gt;
&lt;br /&gt;
# CSS&lt;br /&gt;
#page.stylesheet = fileadmin/template/main.css&lt;br /&gt;
&lt;br /&gt;
# Link to top&lt;br /&gt;
#content.linkToTop &amp;gt;&lt;br /&gt;
tt_content.stdWrap.innerWrap2 = |&amp;lt;br&amp;gt;&amp;lt;div class=&amp;quot;toTop&amp;quot;&amp;gt;&amp;lt;a href=&amp;quot;#top&amp;quot;&amp;gt;nach oben&amp;lt;/a&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
[global]&lt;br /&gt;
&lt;br /&gt;
### ENGLISCH ###&lt;br /&gt;
[globalVar = GP:L = 1]&lt;br /&gt;
config.sys_language_uid = 1&lt;br /&gt;
config.language = en&lt;br /&gt;
config.locale_all = english&lt;br /&gt;
&lt;br /&gt;
# CSS&lt;br /&gt;
#page.stylesheet = fileadmin/template/main_en.css&lt;br /&gt;
&lt;br /&gt;
# Link to top&lt;br /&gt;
#content.linkToTop &amp;gt;&lt;br /&gt;
tt_content.stdWrap.innerWrap2 = &amp;lt;br&amp;gt;&amp;lt;div class=&amp;quot;toTop&amp;quot;&amp;gt;&amp;lt;a href=&amp;quot;#top&amp;quot;&amp;gt;to top&amp;lt;/a&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#...&lt;br /&gt;
&lt;br /&gt;
[global]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Übersetzung nur Anzeigen wenn sie vorhanden ist ===&lt;br /&gt;
Typo3 - Stuttgart Mailing List (Juli 2006)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt; &amp;gt;Hallo ihr alle,&lt;br /&gt;
&amp;gt; &amp;gt;&lt;br /&gt;
&amp;gt; &amp;gt;ich habe eine typo3 3.7.1 installation und möchte eine übersetzung nur dann anzeigen, wenn diese vorhanden ist.&lt;br /&gt;
&amp;gt; &amp;gt;Wenn sie nicht vorhanden ist soll der gesamte menüpunkt rausfliegen.&lt;br /&gt;
&amp;gt; &amp;gt;&lt;br /&gt;
&amp;gt; &amp;gt;Der untenstehende code sollte funktionieren - tut es aber nicht...&lt;br /&gt;
&amp;gt; &amp;gt;Weis da jemand bescheid?&lt;br /&gt;
&amp;gt; &amp;gt;...meine langwierige recherchen haben leider auch nichts ergeben ;-((&lt;br /&gt;
&amp;gt; &amp;gt;&lt;br /&gt;
&amp;gt; &amp;gt;config.linkVars = L&lt;br /&gt;
&amp;gt; &amp;gt;config.sys_language_uid = 0&lt;br /&gt;
&amp;gt; &amp;gt;config.language = de&lt;br /&gt;
&amp;gt; &amp;gt;config.sys_language_mode = strict&lt;br /&gt;
&amp;gt; &amp;gt;config.sys_language_overlay = hideNonTranslated&lt;br /&gt;
&amp;gt; &amp;gt;&lt;br /&gt;
&amp;gt; &amp;gt;lg niko&lt;br /&gt;
&amp;gt; &amp;gt;  &lt;br /&gt;
&amp;gt; &amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hallo Niko,&lt;br /&gt;
&lt;br /&gt;
vielleicht hilft dir dies weiter:&lt;br /&gt;
&lt;br /&gt;
http://www.datenwolken.de/index.php?id=221&lt;br /&gt;
&lt;br /&gt;
und ein Beispiel hier&lt;br /&gt;
&lt;br /&gt;
http://forum.typo3.fr/index.php?showtopic=4236&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 // User defined&lt;br /&gt;
 USERDEF1 = 1&lt;br /&gt;
 USERDEF1.doNotLinkIt = 1&lt;br /&gt;
 USERDEF1.linkWrap = &amp;lt;li class=&amp;quot;disabled&amp;quot;&amp;gt;|&amp;lt;/li&amp;gt;&lt;br /&gt;
 USERDEF1.stdWrap.override = EN || FR || DE&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
li.disabled dann im stylesheet ausblenden ...&lt;br /&gt;
&lt;br /&gt;
Grüße&lt;br /&gt;
Ines&lt;br /&gt;
&lt;br /&gt;
_______________________________________________&lt;br /&gt;
TYPO3-stuttgart mailing list&lt;br /&gt;
TYPO3-stuttgart@lists.netfielders.de&lt;br /&gt;
http://lists.netfielders.de/cgi-bin/mailman/listinfo/typo3-stuttgart&lt;br /&gt;
&lt;br /&gt;
== Datum und Zeit ==&lt;br /&gt;
Oft ist es schwierig herauszufinden wo gerade die Ausgabe von Zeit und Datum konfiguriert wird.&lt;br /&gt;
&lt;br /&gt;
Wenn eine der Extensions ts_language_de oder ts_language_xx installiert ist wird dort der Standard einer andeen Extension (z.B. tt_news) überschrieben. Diese Einstellung kann wieder im eigenen TS überschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Im Template Analyser kann man die Reihenfolge gut sehen.&lt;br /&gt;
&lt;br /&gt;
Beispiel zur Konfiguration:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Examples:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Your site is a &amp;quot;one-language-site&amp;quot;  and you configured the site-language as default language of TYPO3. If you have a ts_language_xx extension installed, to set some country specific settings for other extensions, I suggest to copy the part which refers to tt_news in your main template or an ext template which is included. Here an example for german settings:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# set the TYPO3 language to german&lt;br /&gt;
config.language = de&lt;br /&gt;
# set the PHP locale to german&lt;br /&gt;
config.locale_all = de_DE&lt;br /&gt;
&lt;br /&gt;
# tt_news date &amp;amp; time formats&lt;br /&gt;
plugin.tt_news {&lt;br /&gt;
  archiveTitleCObject {&lt;br /&gt;
    10.strftime = %B - %Y&lt;br /&gt;
  }&lt;br /&gt;
  getRelatedCObject {&lt;br /&gt;
      20.strftime = %d.%m.%Y %H:%M&lt;br /&gt;
  }&lt;br /&gt;
  displaySingle {&lt;br /&gt;
    date_stdWrap.strftime= %d.%m.%y&lt;br /&gt;
    time_stdWrap.strftime= %H:%M&lt;br /&gt;
  }&lt;br /&gt;
  displayLatest {&lt;br /&gt;
    date_stdWrap.strftime= %d.%m.%y&lt;br /&gt;
    time_stdWrap.strftime= %H:%M&lt;br /&gt;
  }&lt;br /&gt;
  displayList {&lt;br /&gt;
    date_stdWrap.strftime= %A %d. %B %Y&lt;br /&gt;
    time_stdWrap.strftime= %d.%m.%y %H:%M&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hint: If the locale_all setting &amp;quot;de_DE&amp;quot; don&amp;#039;t work on your WAMP installation, try to set it to &amp;quot;german&amp;quot;. There are some differences in the handling of the php-locale on windows and linux.  &lt;br /&gt;
&lt;br /&gt;
If your site is a multilanguage site like the &amp;quot;one-tree-fits-all-languages&amp;quot; example from the &amp;quot;testsite&amp;quot; package (see: http://typo3.org/documentation/tips-tricks/multi-language-sites-in-typo3/ ) you can add the country specific settings to the language condition in your TS-setup:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Setting up the language variable &amp;quot;L&amp;quot; to be passed along with links&lt;br /&gt;
config.linkVars = L&lt;br /&gt;
&lt;br /&gt;
# German language, sys_language.uid = 2&lt;br /&gt;
[globalVar = GP:L = 2]&lt;br /&gt;
config.sys_language_uid = 2&lt;br /&gt;
config.language = de&lt;br /&gt;
config.locale_all = de_DE&lt;br /&gt;
&lt;br /&gt;
# set german date &amp;amp; time formats&lt;br /&gt;
plugin.tt_news {&lt;br /&gt;
  archiveTitleCObject {&lt;br /&gt;
    10.strftime = %B - %Y&lt;br /&gt;
  }&lt;br /&gt;
  getRelatedCObject {&lt;br /&gt;
      20.strftime = %d.%m.%Y %H:%M&lt;br /&gt;
  }&lt;br /&gt;
  displaySingle {&lt;br /&gt;
    date_stdWrap.strftime= %d.%m.%y&lt;br /&gt;
    time_stdWrap.strftime= %H:%M&lt;br /&gt;
    age_stdWrap.age =  Minuten | Stunden | Tage | Jahre&lt;br /&gt;
  }&lt;br /&gt;
  displayLatest {&lt;br /&gt;
    date_stdWrap.strftime= %d.%m.%y&lt;br /&gt;
    time_stdWrap.strftime= %H:%M&lt;br /&gt;
  }&lt;br /&gt;
  displayList {&lt;br /&gt;
    date_stdWrap.strftime= %A %d. %B %Y&lt;br /&gt;
    time_stdWrap.strftime= %d.%m.%y %H:%M&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
[global]&lt;br /&gt;
&lt;br /&gt;
# Danish language, sys_language.uid = 1&lt;br /&gt;
[globalVar = GP:L = 1]&lt;br /&gt;
config.sys_language_uid = 1&lt;br /&gt;
config.language = dk&lt;br /&gt;
config.locale_all = danish&lt;br /&gt;
&lt;br /&gt;
# set danish date &amp;amp; time formats&lt;br /&gt;
plugin.tt_news {&lt;br /&gt;
  # sorry, don&amp;#039;t know the danish date &amp;amp; time settings ;-)&lt;br /&gt;
}&lt;br /&gt;
[global]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Felder im Backend für mehrere Sprachen benutzen ==&lt;br /&gt;
&lt;br /&gt;
michael schuhmacher wrote:&lt;br /&gt;
&amp;gt; Hallo,&lt;br /&gt;
&amp;gt; weiss jemand wie ich es anstelle, dass bei einer eigenen extension, im backend bestimmte felder grundsaetzlich fuer alle sprachen stehen sollen? so dass man nicht zb. die selben bilder in den uebersetzungen nochmal angeben muss.&lt;br /&gt;
&lt;br /&gt;
habs schon&lt;br /&gt;
&lt;br /&gt;
in meinem fall in ext_tables.php (oder auch in tca.php)&lt;br /&gt;
&lt;br /&gt;
 &amp;quot;l10n_mode&amp;quot; =&amp;gt; &amp;#039;exclude&amp;#039;,&lt;br /&gt;
&lt;br /&gt;
== Sprachlabel für die Frontendausgabe anpassen ==&lt;br /&gt;
Stichwort Language Label, Sprachlabel, Mehrsprachigkeit&lt;br /&gt;
Bei Mehrsprachigen Extensions werden die Ausgaben für die verschiedenen Sprachen in der Regel in der Datei locallang.xml notiert. Oftmals möchte man diese Ausgaben anpassen, ohne diese Datei zu verändern. Denn nach einem Update würden die Änderungen wieder Rückgängig gemacht. Die Labels für die Sprache lassen sich aber auch über eigene Extensions oder über TypoScript anpassen. &lt;br /&gt;
&lt;br /&gt;
Mit TypoScript funktioniert das etwa so:&lt;br /&gt;
&lt;br /&gt;
 plugin.tt_news._LOCAL_LANG.de.more = mehr &amp;gt;&amp;gt;&lt;br /&gt;
also nach dem Schema:&lt;br /&gt;
 plugin.meinPlugin._LOCAL_LANG.sprachkürzel.labelnahme = meinLabel&lt;br /&gt;
&lt;br /&gt;
== Sprachlabel im Backend anpassen ==&lt;br /&gt;
Quelle: http://typo3-freelancer-berlin.de/typo3-blog/artikel/typo3-backendformulare-label-aendern-per-typoscript.html (Zugriff: 09/2011)&lt;br /&gt;
&lt;br /&gt;
Oftmals möchten Kunden die Bezeichnung einzelner Felder im backend anders benannt haben.&lt;br /&gt;
&lt;br /&gt;
pageTSconfig&lt;br /&gt;
&lt;br /&gt;
 // Label in eigener locallang_db.php überschreiben&lt;br /&gt;
 TCEFORM.table.column.label = LLL:typo3conf/override_locallang_db.php:table.column&lt;br /&gt;
&lt;br /&gt;
// Label direkt in pageTSconfig überschreiben&lt;br /&gt;
&lt;br /&gt;
 TCEFORM.table.column.label = My Title&lt;br /&gt;
 TCEFORM.table.column.label.de = Mein Titel&lt;br /&gt;
&lt;br /&gt;
== Weiterleitung in Abhängigkeit der Browsersprache ==&lt;br /&gt;
Damit der Benutzer gleich auf der richtigen Sprache landet kann man die Extension&lt;br /&gt;
rlmp_language_detection benutzen.&lt;br /&gt;
&lt;br /&gt;
Als Erweiterung gibt es noch die Extension Title Language Detection - Extended( sr_language_detect ) von Stanislas Rolland&lt;br /&gt;
=== Konfiguration für One-Tree Konzept ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
plugin.tx_rlmplanguagedetection_pi1 {&lt;br /&gt;
  defaultLang = de #ISO-Code der Standardsprache anpasssen&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Konfiguration für Multi-Tree Konzept ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
plugin.tx_rlmplanguagedetection_pi1 {&lt;br /&gt;
   useOneTreeMethod = 0&lt;br /&gt;
   multipleTreesRootPages&lt;br /&gt;
   {&lt;br /&gt;
      #PID&amp;#039;s der jeweiligen Sprachen anpassen, ggf. neue zufuegen&lt;br /&gt;
      de = 216&lt;br /&gt;
      en = 120&lt;br /&gt;
      es = 482&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
=== Problem mit Browserseitigem Cache bei Einsatz von rlmplanguagedetection ===&lt;br /&gt;
Um die richtigen Werte für das Caching auszugeben muß in der Konfiguration stehen:&lt;br /&gt;
&lt;br /&gt;
Typoscript:	Zeilennummerierung:  An / Aus&lt;br /&gt;
&lt;br /&gt;
   1.&lt;br /&gt;
      config.sendCacheHeaders = 1 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Diese Funktion bleibt aber unter anderem auf den Seiten wirkungslos, in denen USER_INT Objekte genutzt werden.&lt;br /&gt;
&lt;br /&gt;
Mit der Extention &amp;#039;rlmplanguagedetection&amp;#039; steckt dieses Object in jedem Seiten-Rendering. Das USER_INT Object braucht es aber für die Funktion der Extension.&lt;br /&gt;
&lt;br /&gt;
Da die Extension keine neuen Header mit &amp;#039;Location&amp;#039; und dem GetParameter ausgibt, wenn dieser Parameter bereits in der URL vorhanden ist, braucht es diese USER_INT funktion folglich auch nicht bei jedem Seitenaufruf. Um sie denn in diesem Falle aus den Seiten-Rendering auch auszuschließen habe ich mich für folgendes Konzept entschieden, in dem via TypoScript die Extension einfach ausgeschlossen wird, wenn der GetParameter bereits existiert:&lt;br /&gt;
&lt;br /&gt;
Typoscript:	Zeilennummerierung:  An / Aus&lt;br /&gt;
&lt;br /&gt;
   1.&lt;br /&gt;
      # send Cache Headers&lt;br /&gt;
   2.&lt;br /&gt;
      config.sendCacheHeaders = 1&lt;br /&gt;
   3.&lt;br /&gt;
      # disable USER_INT &amp;#039;rlmplanguagedetection&amp;#039; when GP:L exists&lt;br /&gt;
   4.&lt;br /&gt;
      [globalVar=GP:L=0,GP:L&amp;gt;0]&lt;br /&gt;
   5.&lt;br /&gt;
      plugin.tx_rlmplanguagedetection_pi1 &amp;gt;&lt;br /&gt;
   6.&lt;br /&gt;
      [global] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Das funktioniert, und damit lässt sich die Extension auch wieder für Proxy- oder Clientseitiges Cachen nutzen.[/TS] &lt;br /&gt;
   3. Testen (Browsersprache ändern. Anleitung unten.)&lt;br /&gt;
   4. Falls es Probleme gibt und die Spracherkennung / -weiterleitung nicht funktioniert, kann folgendes im Setup des Root Templates hinzufügt werden. Hier wird die Erweiterung im Page-Element an Position 1000 inkludiert. Diese Einstellung muss ggf. angepasst werden.&lt;br /&gt;
&lt;br /&gt;
      page.1000 &amp;lt; plugin.tx_rlmplanguagedetection_pi1&lt;br /&gt;
&lt;br /&gt;
Tipps zum Testen&lt;br /&gt;
&lt;br /&gt;
Wie stellt man die Sprache des Browsers um? Das Umstellen der Browsersprache:&lt;br /&gt;
&lt;br /&gt;
Firefox&lt;br /&gt;
&lt;br /&gt;
    * Extras &amp;gt; Einstellungen &amp;gt; Reiter Erweitert &amp;gt; Reiter Allgemein (Windowsversion) oder&lt;br /&gt;
      Bearbeiten &amp;gt; Einstellungen &amp;gt; Reiter Erweitert &amp;gt; Reiter Allgemein (Linuxversion)&lt;br /&gt;
    * im Unteren Bereich befindet sich der Abschnitt Sprache, in dem man über den Button &amp;quot;wählen&amp;quot; ein oder mehrere neue Sprachen hinzufügen kann. Die Sprache in der getestet wird steht immer oben.&lt;br /&gt;
&lt;br /&gt;
Internet Explorer IE&lt;br /&gt;
&lt;br /&gt;
    * Extras &amp;gt; Internetoptionen&lt;br /&gt;
    * im Unteren Bereich befindet sich der Button Sprache, mit dem man ein oder mehrere neue Sprachen hinzufügen kann. Die Sprache in der getestet wird steht immer oben.&lt;br /&gt;
&lt;br /&gt;
Wenn es nicht funktioniert&lt;br /&gt;
&lt;br /&gt;
Wenn es nicht funktioniert hat man eventuell die Sprachen nicht richtig eingerichtet. Hier sollte man noch mal die Konfiguration überprüfen.&lt;br /&gt;
Anleitung von rainer-grundel Datum des Zugriffs 1.4.2008, http://www.rainer-grundel.de/wissensdb/typo3/empfohlene_extensions/artikel/article/anzeige_der_website_nach_browsersprache.html&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mehrsprachigkeit und TemplaVoila ==&lt;br /&gt;
Wenn man eine mehrsprachige Seite mit TemplaVoila nutzt. Kann man das Verhalten in der Datenstruktur der TemplaVoila Templates steuern.&lt;br /&gt;
&lt;br /&gt;
TemplaVoila nutzt zur Darstellung seiner Inhalte Flexforms. Die dazugehörigen Parameter für die Darstellung der Mehrsprachigen Datensätze im Backend steuert man daher mit der Flexform T3DataStructure. Konkret sind hier folgende XML-Tags von Bedeutung:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;meta type=&amp;quot;array&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;langDisable type=&amp;quot;integer&amp;quot;&amp;gt;[0|1]&amp;lt;/langDisable&amp;gt;&lt;br /&gt;
        &amp;lt;langChildren type=&amp;quot;integer&amp;quot;&amp;gt;[0|1]&amp;lt;/langChildren&amp;gt;&lt;br /&gt;
    &amp;lt;/meta&amp;gt; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wie gezeigt können diese also entweder den Wert 0 oder 1 enthalten&lt;br /&gt;
===langDisable===&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; Sprachsteuerung durch das Flexform, technisch gesehen bedeutet das, daß die Übersetzungen im Flexform-Datensatz gespeichert werden. Siehe auch langChildren&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; Die Sprachsteuerung durch das Flexform ist abgeschaltet. D.h. Typo3 übernimmt das selbst. Dies ist die geeignete Einstellung für Flexible Content Elemente die zur Gliederung (z.B. 2Spalter) genutzt werden.&lt;br /&gt;
&lt;br /&gt;
===langChildren===&lt;br /&gt;
Hat nur Auswirkung wenn langDisable auf 0 steht.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; Die Inhalte der Flexforms lassen sich Direkt übersetzen (Flagge klicken) und werden zusammengezoge im Backend dargestellt.&lt;br /&gt;
Im Frontend wird die Standardsprache verwendet wenn keine Übersetzung vorhanden ist.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; Keine Direkte übersetzung. Das komplette Flexform wird übersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Seiten ohne Übersetzung im Menü verstecken ==&lt;br /&gt;
Quelle:http://blog.undkonsorten.com/typo3-seite-uebersetzung-menue-verstecken&lt;br /&gt;
&lt;br /&gt;
Datum des Zugriffs: 29.4.2009&lt;br /&gt;
&lt;br /&gt;
16. Januar 2008&lt;br /&gt;
&lt;br /&gt;
Für mehrsprachige TYPO3-Webseiten im One-Tree-Konzept werden standardgemäß die immer alle Menüeintäge in der Standardsprache ausgegeben, insofern für diese keine Übersetzung angelegt wurde. In der Regel ist eine Navigation in zwei verschiedenen Sprachen nicht erwünscht und man möchte Seiten ohne Übersetzungen verstecken. Es gibt zwei Wege, dies umzusetzen.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Lösung über das TYPO3-Backend&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Am einfachsten lässen sich Seiten ohne Übersetzungen ausblenden, indem man unter Seiteneigenschaften &amp;gt; Spracheinstellungen das Verstecke Seiten wenn keine Übersetzung… mit einem kleinen Häckchen versieht.&lt;br /&gt;
&lt;br /&gt;
TYPO3: Sprache verstecken, wenn keine Übersetzung existiert&lt;br /&gt;
&lt;br /&gt;
Wenn für diese Seite - angenommen sie sei deutsche - keine Übersetzung angelegt wurde, man sich aber z.B. gerade im Frontend im englischen Bereich befindet, so wird diese Seite nicht angezeigt.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Lösung per Installtool bzw. localconf.php&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Im Install-Tool &amp;gt; All Configuration gibt es den Eintrag [hidePagesIfNotTranslatedByDefault] . Wenn man hier den Wert TRUE einträgt werden alle Seiten ohne Übersetzung per default versteckt. Dies entspricht folgendem Eintrag in der localconf:&lt;br /&gt;
&lt;br /&gt;
 $TYPO3_CONF_VARS[&amp;#039;FE&amp;#039;][&amp;#039;hidePagesIfNotTranslatedByDefault&amp;#039;] = ‘TRUE’;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Standard-Übersetzung im Menü einblenden per TypoScript&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Man kann per TypoScript-Setup umgekehrt für die Menükonfiguration angeben, dass Seiten generell in der default-Sprache ausgegeben werden, insofern keine Übersetzung vorliegt. Das sieht dann so aus:&lt;br /&gt;
&lt;br /&gt;
 temp.navigation = HMENU&lt;br /&gt;
 temp.navigation {&lt;br /&gt;
 …&lt;br /&gt;
 protectLvar = all&lt;br /&gt;
 …&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
protectLvar kennt die Werte 1 und all. Mit all wird der Wert des Kontrollkästchens überschrieben und Seiten ohne Übersetzungen werden immer ausgegegen.&lt;/div&gt;</summary>
		<author><name>178.7.132.100</name></author>
	</entry>
	<entry>
		<id>https://wiki.stephanschlegel.de/index.php?title=Monopoly&amp;diff=19025</id>
		<title>Monopoly</title>
		<link rel="alternate" type="text/html" href="https://wiki.stephanschlegel.de/index.php?title=Monopoly&amp;diff=19025"/>
		<updated>2012-03-07T14:32:47Z</updated>

		<summary type="html">&lt;p&gt;178.7.132.100: /* Geldverteilung deutsches Monopoly (DM) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Geldverteilung deutsches Monopoly (DM) ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Startkapital 30.000 - in verschiedenen Versionen gibt es verschiedene Verteilungen. Die Variante ist die aus unserem Spiel&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Variante 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1 x 10 000&lt;br /&gt;
6 x 2 000&lt;br /&gt;
4 x 1 000&lt;br /&gt;
3 x 400&lt;br /&gt;
10 x 200&lt;br /&gt;
7 x 100&lt;br /&gt;
5 x 20&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
---------------------&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Variante 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
2x 10.000&lt;br /&gt;
4x 2000&lt;br /&gt;
1x 1000&lt;br /&gt;
1x 400&lt;br /&gt;
2x 200&lt;br /&gt;
1x 100&lt;br /&gt;
5x 20 &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
----------------------&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Variante 3 (mit 50ern)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
2 x 10.000&lt;br /&gt;
3 x 2.000&lt;br /&gt;
2 x 1.000&lt;br /&gt;
2 x 500&lt;br /&gt;
6 x 100&lt;br /&gt;
6 x 50&lt;br /&gt;
5 x 20&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>178.7.132.100</name></author>
	</entry>
	<entry>
		<id>https://wiki.stephanschlegel.de/index.php?title=Monopoly&amp;diff=19024</id>
		<title>Monopoly</title>
		<link rel="alternate" type="text/html" href="https://wiki.stephanschlegel.de/index.php?title=Monopoly&amp;diff=19024"/>
		<updated>2012-03-07T14:31:46Z</updated>

		<summary type="html">&lt;p&gt;178.7.132.100: Die Seite wurde neu angelegt: „ == Geldverteilung deutsches Monopoly (DM) ==   Startkapital 30.000 - in verschiedenen Versionen gibt es verschiedene Verteilungen. Die Variante ist die aus unser…“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Geldverteilung deutsches Monopoly (DM) ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Startkapital 30.000 - in verschiedenen Versionen gibt es verschiedene Verteilungen. Die Variante ist die aus unserem Spiel&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Variante 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
1 x 10 000&lt;br /&gt;
6 x 2 000&lt;br /&gt;
4 x 1 000&lt;br /&gt;
3 x 400&lt;br /&gt;
10 x 200&lt;br /&gt;
7 x 100&lt;br /&gt;
5 x 20&lt;br /&gt;
&lt;br /&gt;
---------------------&lt;br /&gt;
&lt;br /&gt;
2x 10.000&lt;br /&gt;
4x 2000&lt;br /&gt;
1x 1000&lt;br /&gt;
1x 400&lt;br /&gt;
2x 200&lt;br /&gt;
1x 100&lt;br /&gt;
5x 20 &lt;br /&gt;
&lt;br /&gt;
----------------------&lt;br /&gt;
&lt;br /&gt;
2 x 10.000&lt;br /&gt;
3 x 2.000&lt;br /&gt;
2 x 1.000&lt;br /&gt;
2 x 500&lt;br /&gt;
6 x 100&lt;br /&gt;
6 x 50&lt;br /&gt;
5 x 20&lt;/div&gt;</summary>
		<author><name>178.7.132.100</name></author>
	</entry>
	<entry>
		<id>https://wiki.stephanschlegel.de/index.php?title=Gesundheitsregion-rtz&amp;diff=19023</id>
		<title>Gesundheitsregion-rtz</title>
		<link rel="alternate" type="text/html" href="https://wiki.stephanschlegel.de/index.php?title=Gesundheitsregion-rtz&amp;diff=19023"/>
		<updated>2012-03-06T14:53:50Z</updated>

		<summary type="html">&lt;p&gt;178.7.132.100: /* Benutzer anlegen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dies ist eine alte Version die neue Seite liegt unter&lt;br /&gt;
&lt;br /&gt;
[[Gesundheitsregion_Reutlingen_Tübingen_Zollernalb]] &lt;br /&gt;
&lt;br /&gt;
== Benutzer anlegen ==&lt;br /&gt;
Im Backend:&lt;br /&gt;
# Unter Gesundheitskalender &amp;gt; Assets den &amp;#039;&amp;#039;&amp;#039;Veranstalter anlegen&amp;#039;&amp;#039;&amp;#039; (List Ansicht). Am besten gleich die ID des neuen Veranstalters merken.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Ordner für die Datensätze&amp;#039;&amp;#039;&amp;#039; anlegen, in den Eigenschaften muß unter &amp;quot;Allgemeine Datensatzsammlung&amp;quot; der &amp;#039;&amp;#039;&amp;#039;Ordner Assets&amp;#039;&amp;#039;&amp;#039; ausgewählt werden, sonst können keine Veranstalter ausgewählt werden.&lt;br /&gt;
# Neue &amp;#039;&amp;#039;&amp;#039;Benutzergruppe Bereich: [meinBereich]&amp;#039;&amp;#039;&amp;#039; anlegen wobei [meinBereich] ein frei wählbarer Name ist. In dieser den &amp;#039;&amp;#039;&amp;#039;DB-Mount&amp;#039;&amp;#039;&amp;#039; für den neu erstellten Ordner angeben und im &amp;#039;&amp;#039;&amp;#039;UserTS&amp;#039;&amp;#039;&amp;#039; die Voreinstellung für den Veranstalter festlegen (ID des im 1. Schritt angelegten Veranstalters: TCAdefaults.tx_gbseminars_seminars.organizerid = [id des Veranstalters]&lt;br /&gt;
# Neuen &amp;#039;&amp;#039;&amp;#039;Backend Benutzer&amp;#039;&amp;#039;&amp;#039; anlegen und die Gruppen &amp;quot;Rolle: Kalender Redakteur&amp;quot; und die neu angelegte Gruppe Bereich: [meinBereich]&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Zugriffsrechte&amp;#039;&amp;#039;&amp;#039; im Modul Zugriff so Einstellen das der neue Benutzer dort Datensätze anlegen kann (Gruppe und Besitzer auf entsprechenden Bereich bzw. User und Rechte für Seite anzeigen und Inhalte bearbeiten)&lt;/div&gt;</summary>
		<author><name>178.7.132.100</name></author>
	</entry>
</feed>