Navigation
 Startseite
 Fachbücher
 Anzeigenmarkt
 Forum
 Webmaster News
 Script Newsletter
 Kontakt
 Script Installation
 Php
 Php Tutorials
 Webhoster Vergleich
 Impressum

Community-Bereich
 kostenlos Registrieren
 Anmelden
 Benutzerliste

Script Datenbank
 Script Archiv
 Script Top 20
 Screenshots
 Testberichte

Suche
 

Unsere Php Scripts
 Counter Script
 Umfrage Script
 Bilder Upload Script
 Terminverwaltung
 Simple PHP Forum
 RSS Grabber

Tools und Generatoren
 .htpasswd Generator
 md5 Generator
 base64 Generator
 Markdown to HTML
 Colorpicker
 Unix timestamp Tool
 Unit Test Generator
 TLD Liste
 Webkatalog‑Verzeichnis

Artfiles.de
Bietet Serviceorientierte...
https://www.Artfiles.de
Hosterplus.de
Bekommen Sie Speicherplatz (Webspace), Domains...
https://www.Hosterplus.de
 
 
 

E-Mail versenden mit PHP

Sie befinden sich: Home > Php > E-Mail versenden mit PHP

Mit mail(); stellt PHP eine einfach zu verwendende, und dennoch sehr hoch konfigurierbare Funktion zum versenden von E-Mails zur Verfügung. Der Syntax der mail(); Funktion ist fast selbsterklärend.

Der Syntax ist:

mail ( string $empfänger, string $betreff, string $nachricht [, string $zusatz_header [, string $zusatz_parameters]] )

Es wird von der Funktion sichekt zurückgegeben true oder false, nach der Ausführung. Dadurch haben sie die Möglichkeit über eine If- Anweisung die Erfolgsmeldung gegebenenfalls Fehlermeldung nachträglich anzupassen. Ein Beispiel wie man dies einsetzen, wird im unteren Teil dieser Seite erklärt.

Als erstes wollen wir auf die einzelnen Variablen eingehen, womit man die Funktion ansteuern kann.


$empfänger - mail() erlaubt es auch mehr als einen Empfänger sichekt anzugeben.

Dieser String für den Empf änger muss RFC2822 konform sein, um dies zu verdeutlichen ein paar Beispiele:

  1. benutzer@example.com
  2. benutzer@example.com, benutzer2@example.com
  3. Name <benutzer@example.com>
  4. Name <benutzer@example.com>, Name2 <benutzer2@example.com>

$betreff - Stellt den eigentlichen Betreff der E-Mail dar. Wichtig ist, das $betreff keine Zeilenumbrüche enthalten darf, da ansonsten die E-Mail nicht richtig versendet werden kann.

$nachricht - ist der eigentlichen Inhalt der Mail.

Zu beachten ist das jede Zeile durch ein LF - Zeichen \n ( LF steht für Line Feed ) getrennt werden muss, und das eine Zeile nicht mehr als 70 Zeichen enthalten sollte. Sofern PHP sichekt mit einem SMTP Server kommuniziert und unter Windows verwendet wird, ist zu beachten das ein Punkt (.) am Anfang einer Zeile entfernt wird. Soll dies verhindert werden kann der Punkt durch zwei Punkte ersetzen werden.

Hier ein kleines Beispiel wie einfach man dies mit str_replace() machen kann.

<?php
$nachricht = str_replace("\n.", "\n..", $nachricht);
?>
$zusatz_headers - Ist optional und muss nicht angegeben werden. Dieser String stellt eine Zeichenkette dar, die am Ende des E-Mail-Headers eingefügt werden soll. Dieses optionale Parameter wird hauptsächlich für Angaben wie From, CC oder BCC verwendet. Wenn mehrere dieser Parameter verwendet werden sollen müssen diese durch ein CRLF - Zeichen ( \r\n ) getrennt werden. Um überhaupt eine Mail versenden zu können MUSS ein From-header vorhanden sein.

Wichtig ist in diesem Zusammenhang der Umstand das die php.ini Datei dahin gehend angepasst werden kann, das nicht zwangläufig bei jedem Aufruf der mail(); Funktion explizit dieser String als additionales Parameter übergeben werden muss. Zu beachten ist, das einige UNIX Mail Transfer Agents das LF - Zeichen durch ein CRLF – Zeichen ersetzen, wodurch dann das CR – Zeichen doppelt vorhanden ist. In Ausnahmefällen reicht es dann, nur ein LF zu verwenden. ( Dies verstößt explizit gegen die RFC 2822 Norm )

$zusatz_parameters - Dieser Parameter ist optional und muss nicht zwingend angegeben werden. Der Parameter wird dazu verwendet zusätzliche Parameter an das entsprechende Mail- Programm zu übergeben. Hierbei ist es wichtig das der Sendmail Pfad in der php.ini Datei entsprechend gesetzen ist, um das Ziel der Parameterübergabe zu haben. Benutzen wird diese Funktion häufig, um eine nicht zustellbar E-Mail an eine bestimmte E-Mail-Adresse weiterzuleiten, dazu sollte Sendmail mit der -f Option benutzen werden. Um Fehler zu vermeiden sollte der Benutzer unter dem der Webserver läuft ebenfalls als bekannter Benutzer in der Sendmail - Konfiguration ( Diese Datei befindet sich meistens unter /etc/mail/trusted-users ) eingetragen sein.

Hinweis: Der frühere safe_mode wurde in PHP 5.4 vollständig entfernt und existiert in modernen PHP-Versionen nicht mehr. Der -f Parameter kann daher ohne Einschränkungen verwendet werden.

Ein kurzes Beispiel zeigt den Gebrauch der mail() Funktion

<?php
/*
 * In der Variabel $empfaenger wird
 * die Empfänger E-Mail-Adresse gespeichert.
 */
$empfaenger = 'niemand@example.com';

/*
 * In der Variabel $betreff wird
 * der Betreff gespeichert. Es darf kein
 * Zeilenumbruch enthalten sein.
 */
$betreff = 'Betreff der E-Mail';

/*
 * In der Variabel $nachricht_text wird
 * der Text der Nachricht gespeichert.
 */
$nachricht_text = 'Das ist der Nachrichtentext';

/*
 * In der Variabel $header wird
 * der Absender, Antwortet E-mail-Adresse sowie
 * welche PHP-Version für den Versand zuständig
 * ist gespeichert. Es muss explizit für die Angaben
 * ein direkter Zeilenumbruch generiert werden.
 *
 *  Den Zeilenumbruch machen wir mit "\r\n"
 */
$header = 'MIME-Version: 1.0'. "\r\n";
$header .= 'From: webmaster@example.com' . "\r\n";
$header .= 'Reply-To: webmaster@example.com' . "\r\n";
$header .= 'X-Mailer: PHP/' . phpversion(). "\r\n";
$header .= 'Content-Type:text/plain; charset=UTF-8';

/*
 * Nach dem wir alle Parameter definiert haben
 * können wir sie E-Mail direkt an unser Mailprogramm
 * übergeben.
 *
 * Mit der If-Anweisung prüfen wir den zurückgegebenen
 * Wert der Mailfunktion.  Wir setzten direkt vor dem
 * Mailfunktion ein @ Zeichen damit keine PHP
 * Fehlermeldung ausgegeben werden.
 */
if (@mail($empfaenger, $betreff, $nachricht_text,
    $header) === true) {
    /*
     * Wenn die Mailfunktion keinen Fehler
     * zurückgeliefert geben wir den Text
     * dafür aus, dass die E-Mail erfolgreich
     * versendet wurde.
     */
    echo 'Die erste E-Mail wurde erfolgreich versendet';
} else {
    /*
     * Sollte Mailfunktion einen Fehler
     * zurückgeben, geben wir den Betrachter
     * dieser Seite eine Fehlermeldung aus.
     */
    echo 'Die erste E-Mail konnten nicht versendet werden';
}

/*
 * Nachfolgend  versenden wir eine E-Mail mit dem 5. Parameter.
 * Diese E-Mail wird nur versendet, wenn der Safe_Mode=OFF ist.
 */

/*
 * Hinweis: safe_mode existiert seit PHP 5.4 nicht mehr.
 * Die folgende Prüfung ist in modernem PHP nicht
 * mehr erforderlich.
 */
if (ini_get('safe_mode') == '0' ) {
    /*
     * Wenn der Safe_Mode gesetzt ist auf OFF,
     * versenden jetzt nun die E-Mail.
     */
    if (@mail($empfaenger, $betreff, $nachricht_text,
        $header, '-fwebmaster@example.com') === true) {
        /*
         * Wenn die Mailfunktion keinen Fehler
         * zurückgeliefert geben wir den Text
         * dafür aus, dass die E-Mail erfolgreich
         * versendet wurde.
         */
        echo 'Die zweite E-Mail wurde erfolgreich versendet';
    } else {
        /*
         * Sollte Mailfunktion einen Fehler
         * zurückgeben, geben wir den Betrachter
         * dieser Seite eine Fehlermeldung aus.
         */
        echo 'Die zweite E-Mail konnten nicht versendet werden';
    }
}
?>

Wenn sie diesen Code in eine email_senden.php Datei speichern und diese sichekt in den Browser aufrufen, versendet automatisch der Mailserver zwei E-Mails. Man hat nun die Möglichkeit zum Beispiel, mit der Übergabe von Variablen an die email_senden.php Datei ein einfaches Kontaktformular zu erstellen.

Häufig bekommen wir die Frage, wie so werden Umlaute in der E-Mail falsch dargestellt?

Dies kann verschiedene Ursachen haben.

Prüfen Sie den Charset ihrer Webseite. Der Browser sollte das Formular als UTF-8 interpretieren. Des Weiteren sollten Sie in ihren Editor überprüfen, ob die Kodierung der Datei auf UTF-8 gestellt ist. In PHPStorm ist das unten rechts. Über das Projektverzeichnis – File Encoding können Sie die Datei von zum Beispiel ISO-8859-1 auf UTF-8 stellen.

Zusätzlich muss der Charset im Mail Header angegeben werden. Diese wird in der Variable $header hinterlegt. Wenn die Umlaute immer noch falsch dargestellt werden in der E-Mail, müssen die PHP Einstellungen sowie die Apache Einstellungen überprüft werden. Dazu sollten Sie sich an ihren Webhoster wenden.

Eine Erklärung, wie Sie eine "E-Mail mit einen Dateianhang versenden" finden Sie in unsern Php Tutorial Bereich.

mail() ist Legacy: Warum Sie heute auf Bibliotheken setzen

Die eingebaute Funktion mail() ist so alt wie PHP selbst und macht auf den ersten Blick einen sehr einfachen Eindruck. Sie geben Empfänger, Betreff, Text und ein paar Header mit, und schon landet die Nachricht im Posteingang. In der Praxis stellst Sie aber schnell fest, dass diese Einfachheit teuer bezahlt ist. mail() reicht den Versand an das lokale sendmail-Binär weiter und gibt sich keinerlei Kontrolle über Authentifizierung, TLS, Bounce-Handling oder Charset-Encoding. Auf modernen Hostings ist die Wahrscheinlichkeit hoch, dass Ihre Mail entweder sichekt im Spam landet oder gar nicht erst ankommt.

Hinzu kommt, dass viele Provider den lokalen Mailversand abgeschaltet haben und stattdessen einen authentifizierten SMTP-Relay erwarten. Genau hier kommen Bibliotheken wie PHPMailer oder der Symfony-Mailer ins Spiel. Sie sprechen sichekt SMTP, kümmern sich um TLS-Verbindungen, MIME-Strukturen, Anhänge und korrekt kodierte Header. Sie investieren einmalig fünf Minuten in die Konfiguration und sparen sich dafür jede Menge merkwürdige Zustellprobleme. Eine ausführliche Anleitung dazu finden Sie im Tutorial PHPMailer mit SMTP.

PHPMailer mit SMTP konfigurieren

Die Einrichtung von PHPMailer ist denkbar überschaubar. Sie installieren das Paket per Composer, laden die Klassen, übergeben Hostname, Port, Benutzer und Passwort Ihres SMTP-Servers und schickst die erste Testmail. Wichtig ist, dass Sie die Verbindung explizit verschlüsselst. Für Port 587 nutzen Sie STARTTLS, für Port 465 implizites SMTPS. Klartext-SMTP auf Port 25 hat heute keinen Platz mehr in produktivem Code.

<?php
declare(strict_types=1);

require 'vendor/autoload.php';

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

$mail = new PHPMailer(true); /* true aktiviert Exceptions */

try {
    $mail->isSMTP();
    $mail->Host       = 'smtp.example.com';
    $mail->SMTPAuth   = true;
    $mail->Username   = 'noreply@example.com';
    $mail->Password   = getenv('SMTP_PASSWORT') ?: '';
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
    $mail->Port       = 587;
    $mail->CharSet    = PHPMailer::CHARSET_UTF8;

    $mail->setFrom('noreply@example.com', 'Mein Shop');
    $mail->addAddress('kunde@example.com', 'Lisa Beispiel');
    $mail->Subject = 'Willkommen';
    $mail->Body    = 'Schoen, dass du dabei bist!';

    $mail->send();
} catch (Exception $e) {
    error_log('Mail fehlgeschlagen: ' . $mail->ErrorInfo);
}

Beachte, dass das Passwort niemals sichekt im Code stehen sollte. Legen Sie es in eine Umgebungsvariable, eine .env-Datei oder einen Secret-Manager. Wenn Sie den Versand testen, aktiviere mit $mail->SMTPDebug = SMTP::DEBUG_SERVER; kurzzeitig die Debug-Ausgabe.

HTML-Mail mit Plaintext-Fallback

Eine reine HTML-Mail ohne Textalternative ist ein Klassiker für den Spamfilter. Spam-Scoring-Systeme wie SpamAssassin werten jede Mail negativ, die keinen multipart/alternative-Part mit Klartext anbietet. Außerdem gibt es immer noch Clients, die HTML nicht oder nur eingeschränkt darstellen. Eine gute Mail enthält deshalb beides: eine sauber formatierte HTML-Variante und einen lesbaren Text-Fallback.

<?php
declare(strict_types=1);

$mail->isHTML(true);
$mail->Subject = 'Deine Rechnung ist da';

$mail->Body = '<h1>Hallo Lisa</h1>'
    . '<p>deine Rechnung Nummer <strong>R-2026-042</strong> '
    . 'liegt bereit.</p>';

$mail->AltBody = "Hallo Lisa,\n\n"
    . "deine Rechnung R-2026-042 liegt bereit.\n";

Wenn Sie dynamische Inhalte einsetzen, denk an saubere Ausgabe. Alles, was vom Nutzer kommt, läuft im HTML-Body durch htmlspecialchars. Andernfalls riskierst Sie HTML-Injection.

Anhänge richtig mitsenden

Anhänge sind das klassische Beispiel dafür, warum man mail() heute meidet. Sie müsstest manuell MIME-Boundaries setzen, Base64 kodieren und die Header korrekt verschachteln. Mit PHPMailer reduziert sich das auf einen Methodenaufruf. Wichtig ist, dass Sie den MIME-Type sinnvoll setzen, damit der Mail-Client die Datei korrekt öffnet.

<?php
declare(strict_types=1);

/* Datei vom Server-Pfad anhaengen. */
$mail->addAttachment(
    '/var/app/rechnungen/R-2026-042.pdf',
    'rechnung_R-2026-042.pdf',
    PHPMailer::ENCODING_BASE64,
    'application/pdf'
);

/* Auch direkt aus einem String moeglich. */
$pdfBinary = generierePdf($rechnung);
$mail->addStringAttachment(
    $pdfBinary,
    'kassenbon.pdf',
    PHPMailer::ENCODING_BASE64,
    'application/pdf'
);

/* Inline-Bild fuer den HTML-Body, referenziert per cid: */
$mail->addEmbeddedImage(
    '/var/app/img/logo.png',
    'logo_cid',
    'logo.png',
    PHPMailer::ENCODING_BASE64,
    'image/png'
);
$mail->Body = '<img src="cid:logo_cid" alt="Logo"> ...';

Achten Sie auf die Grösse. Viele Mailserver akzeptieren keine Nachrichten über 25 MB, einige limitieren sogar bei 10 MB. Wenn Sie grössere Dateien verschicken wollen, lade sie auf Ihren Server und versende stattdessen einen signierten Download-Link. Das ist sicherer, schneller und zustellfreundlicher.

Header korrekt setzen: From, Reply-To und Return-Path

Viele Zustellprobleme entstehen, weil Header falsch oder widersprüchlich gesetzen werden. Drei Felder solltest Sie immer bewusst einstellen. Der From-Header gehört zwingend zu einer Domain, über die Sie auch versenden dürfen. Setzt Sie dort eine fremde Adresse ein, schlägt SPF an und die Mail landet im Spam. Der Reply-To-Header steuert, wohin Antworten gehen sollen.

<?php
declare(strict_types=1);

$mail->setFrom('noreply@example.com', 'Mein Shop');
$mail->addReplyTo('support@example.com', 'Shop-Support');

/* Der Return-Path (Envelope-Sender) ist die Adresse,
   an die Bounces gehen. */
$mail->Sender = 'bounces@example.com';

/* List-Unsubscribe Header fuer Newsletter. */
$mail->addCustomHeader(
    'List-Unsubscribe',
    '<mailto:unsubscribe@example.com>'
);

Der wichtigste Punkt: Setzen Sie niemals einen From-Header mit der Adresse Ihres Nutzers. Wenn Sie beispielsweise ein Kontaktformular hast und dort die E-Mail des Absenders sichekt als Absender einsetzen, ist das ein Spoofing-Klassiker, der Ihre Reputation zerstört. Die Nutzeradresse gehört in Reply-To, der From bleibt Ihre eigene, authentifizierte Domain.

SPF, DKIM und DMARC: Spamfilter freundlich stimmen

Auch wenn Ihr PHP-Code perfekt arbeitet, entscheidet am Ende der DNS Ihrer Domäne über Zustellung oder Spam-Ordner. Drei DNS-Einträge sind heute Standard und ohne sie wird es schwer. SPF (Sender Policy Framework) listet, welche Server überhaupt im Namen Ihrer Domäne versenden dürfen. DKIM (DomainKeys Identified Mail) signiert jede Mail kryptografisch, sodass der Empfänger prüfen kann, ob sie unterwegs manipuliert wurde. DMARC verbindet beides und sagt dem Empfänger, was er tun soll, wenn SPF oder DKIM versagen.

; SPF: nur dieser SMTP-Server darf fuer example.com versenden
example.com.   IN TXT "v=spf1 ip4:203.0.113.42 -all"

; DKIM: Public Key fuer den Selector mail2026
mail2026._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkq..."

; DMARC: Bei Fehlschlag in Quarantaene
_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com"

Die DNS-Einträge selbst kommen aus dem Verwaltungsbereich Ihres Domain-Hosters oder Ihres E-Mail-Dienstleisters. PHP hat mit der Konfiguration nichts zu tun, wohl aber mit der Konsequenz: Wenn Sie SPF eng stellst und dann plötzlich aus Ihrem Webhoster heraus über dessen lokales Sendmail verschicken, schlägt SPF fehl und Ihre Mails verschwinden.

E-Mail-Versand-Flow: vom Skript bis zum Postfach

Damit die Aufgabenverteilung klar wird, hilft eine kompakte Visualisierung. Vom Moment an, in dem Ihre PHP-Anwendung das Senden anstösst, bis die Mail beim Empfänger im Posteingang liegt, sind mehrere Stationen beteiligt. Jede davon kann den Versand stoppen, weshalb Sie bei Problemen wissen solltest, wo Sie suchen müssen.

flowchart LR
    A[PHP-Anwendung] --> B[PHPMailer]
    B --> C[SMTP-Relay]
    C --> D[Empfaenger-MX]
    D --> E[Postfach]

Hakt es bei A oder B, sehen Sie das in Ihrem Application-Log oder über $mail->ErrorInfo. Probleme bei C, also dem SMTP-Relay, werden meist als 5xx-Fehler beim send()-Aufruf zurückgegeben. Bei D entscheidet der empfangende Mailserver anhand von SPF, DKIM und DMARC über Annahme oder Ablehnung. Bei E kommen schliesslich noch Spamfilter, Regeln und Ordnerzuweisungen ins Spiel.

Praxisbeispiel: Kontaktformular-Mailer mit PHPMailer

Zum Abschluss bauen Sie sich ein robustes Kontaktformular zusammen, das alle bisherigen Punkte berücksichtigt. Eingaben werden validiert, der From bleibt Ihre eigene Domain, die Nutzeradresse landet im Reply-To, und die Mail wird sowohl als HTML als auch als Klartext verschickt. Für die Validierung der E-Mail-Adresse setzen Sie auf filter_var. Für die Ausgabe im HTML-Body kommt htmlspecialchars zum Einsatz.

<?php
declare(strict_types=1);

require __DIR__ . '/vendor/autoload.php';

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception as MailerException;

/* 1. Eingaben einsammeln und trimmen. */
$name    = trim((string)($_POST['name']    ?? ''));
$absend  = trim((string)($_POST['email']   ?? ''));
$nachr   = trim((string)($_POST['message'] ?? ''));

/* 2. Validierung. Bei Fehlern raus mit klarer Meldung. */
$fehler = [];
if ($name === '' || mb_strlen($name) > 100) {
    $fehler[] = 'Name fehlt oder ist zu lang';
}
if (filter_var($absend, FILTER_VALIDATE_EMAIL) === false) {
    $fehler[] = 'Ungueltige E-Mail-Adresse';
}
if (mb_strlen($nachr) < 10) {
    $fehler[] = 'Nachricht ist zu kurz';
}
if ($fehler !== []) {
    http_response_code(422);
    echo implode(' / ', array_map('htmlspecialchars', $fehler));
    exit;
}

/* 3. PHPMailer aufsetzen und Mail bauen. */
$mail = new PHPMailer(true);

try {
    $mail->isSMTP();
    $mail->Host       = 'smtp.example.com';
    $mail->SMTPAuth   = true;
    $mail->Username   = 'noreply@example.com';
    $mail->Password   = getenv('SMTP_PASSWORT') ?: '';
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
    $mail->Port       = 587;
    $mail->CharSet    = PHPMailer::CHARSET_UTF8;

    /* From bleibt unsere Domain, Antworten gehen
       an den echten Absender. */
    $mail->setFrom('noreply@example.com', 'Kontaktformular');
    $mail->addAddress('support@example.com', 'Support');
    $mail->addReplyTo($absend, $name);

    $mail->Subject = 'Neue Kontaktanfrage von ' . $name;

    /* HTML mit escapeten Werten. */
    $mail->isHTML(true);
    $mail->Body =
        '<h2>Neue Anfrage</h2>'
        . '<p><strong>Name:</strong> '
        . htmlspecialchars($name, ENT_QUOTES, 'UTF-8') . '</p>'
        . '<p><strong>E-Mail:</strong> '
        . htmlspecialchars($absend, ENT_QUOTES, 'UTF-8') . '</p>'
        . '<p><strong>Nachricht:</strong><br>'
        . nl2br(htmlspecialchars($nachr, ENT_QUOTES, 'UTF-8'))
        . '</p>';

    $mail->AltBody =
        "Neue Anfrage\n"
        . "Name: {$name}\n"
        . "E-Mail: {$absend}\n\n"
        . "Nachricht:\n{$nachr}\n";

    $mail->send();
    echo 'Vielen Dank, deine Nachricht ist unterwegs.';
} catch (MailerException $e) {
    error_log('Kontaktformular: ' . $mail->ErrorInfo);
    http_response_code(500);
    echo 'Versand momentan nicht moeglich, bitte spaeter erneut versuchen.';
}

Mit diesem Skript haben Sie ein produktionstaugliches Kontaktformular. Es validiert die Eingaben mit filter_var, schützt vor HTML-Injection per htmlspecialchars, hält sich an die Header-Regeln und liefert sowohl HTML als auch Plaintext. Wenn Sie es noch weiter härten wollen, ergänze einen Honeypot oder ein Captcha gegen Bots, ein Rate-Limit pro IP und einen Token-Check gegen CSRF.




weiter zum nächsten Kapitel: Grundlegende Konzepte und Strukturen von PHP Function