PHP Mails ueber SMTP versenden

Die eingebaute mail()-Funktion von PHP ist auf den meisten Systemen unzuverlässig und landet oft im Spam.
Wer Mails direkt über einen SMTP-Server verschickt hat deutlich mehr Kontrolle.

Ohne externe Bibliothek geht das über Sockets — hier eine einfache Funktion die für den Alltag reicht.

function smtpMail(array $cfg, string $to, string $subject, string $body): bool
{
    $sock = fsockopen('ssl://' . $cfg['host'], $cfg['port'], $errno, $errstr, 10);
    if (!$sock) return false;

    $read = fn() => fgets($sock, 512);
    $send = function(string $cmd) use ($sock, $read): string {
        fputs($sock, $cmd . "\r\n");
        return $read();
    };

    $read(); // Banner
    $send('EHLO ' . $cfg['host']);
    $read(); $read(); $read(); $read(); // Multi-line EHLO response

    $send('AUTH LOGIN');
    $read();
    $send(base64_encode($cfg['user']));
    $read();
    $send(base64_encode($cfg['pass']));
    $read();

    $send('MAIL FROM:<' . $cfg['from'] . '>');
    $send('RCPT TO:<' . $to . '>');
    $send('DATA');
    $read();

    $headers  = "From: {$cfg['from']}\r\n";
    $headers .= "To: $to\r\n";
    $headers .= "Subject: $subject\r\n";
    $headers .= "MIME-Version: 1.0\r\n";
    $headers .= "Content-Type: text/plain; charset=UTF-8\r\n";
    fputs($sock, $headers . "\r\n" . $body . "\r\n.\r\n");
    $read();

    $send('QUIT');
    fclose($sock);
    return true;
}

Verwendung

smtpMail([
    'host' => 'smtp.mailgun.org',
    'port' => 465,
    'user' => 'postmaster@meinedomain.de',
    'pass' => 'smtp-passwort',
    'from' => 'noreply@meinedomain.de',
], 'empfaenger@beispiel.de', 'Betreff', 'Nachrichtentext');

Für HTML-Mails den Content-Type auf text/html ändern und HTML im Body übergeben.
Wer Attachments braucht oder komplexere Anforderungen hat ist mit PHPMailer besser bedient.