Tutorial
E-Mails mit PHP senden
Senden Sie E-Mails aus jeder PHP-App mit dem SDK emailit/emailit-php, mit einfachem cURL oder per SMTP mit PHPMailer und verifizieren Sie Emailit-Webhook-Signaturen.
Diese Anleitung behandelt den E-Mail-Versand aus einer PHP-Anwendung ohne Framework: mit dem offiziellen SDK emailit/emailit-php, mit einfachem cURL oder per SMTP mit PHPMailer. Außerdem zeigt sie einen Webhook-Endpunkt, der Signaturen verifiziert. Sie verwenden Laravel? Folgen Sie stattdessen der Anleitung für Laravel.
Voraussetzungen
- PHP 8.1 oder neuer und Composer.
- Eine verifizierte Versanddomain, zum Beispiel
acme.com. - Ein API-Schlüssel. Ein reiner Sende-Schlüssel, der auf Ihre Domain beschränkt ist, genügt.
- Solange Ihr Workspace keinen Produktionszugang hat, können Sie nur an die Konto-E-Mail-Adressen von Workspace-Mitgliedern senden.
SDK installieren
composer require emailit/emailit-phpDas SDK verwendet Guzzle für HTTP; Composer installiert es automatisch mit.
API-Schlüssel konfigurieren
Setzen Sie den Schlüssel als Umgebungsvariable in Ihrem Webserver, Ihrem PHP-FPM-Pool oder Ihrem Hosting-Panel und lesen Sie ihn zur Laufzeit:
export EMAILIT_API_KEY=secret_••••••••••••••••••••••••••••••••$apiKey = getenv('EMAILIT_API_KEY');Wenn Sie eine .env-Datei mit einem Paket wie vlucas/phpdotenv laden, halten Sie diese Datei außerhalb des Web-Roots und aus der Versionsverwaltung heraus.
E-Mail senden
require __DIR__.'/vendor/autoload.php';
$emailit = Emailit::client(getenv('EMAILIT_API_KEY'));
$email = $emailit->emails()->send([
'from' => 'Acme <hello@acme.com>',
'to' => 'ada@example.com',
'subject' => 'Your receipt from Acme',
'html' => '<p>Thanks for your order.</p>',
'text' => 'Thanks for your order.',
]);
echo $email->id; // em_…Derselbe Aufruf akzeptiert cc, bcc, reply_to, attachments, template mit variables, scheduled_at und tracking. Um eine Datei anzuhängen, kodieren Sie sie in Base64:
$email = $emailit->emails()->send([
'from' => 'Acme Billing <billing@acme.com>',
'to' => 'ada@example.com',
'subject' => 'Invoice INV-1042',
'html' => '<p>Your invoice is attached.</p>',
'attachments' => [[
'filename' => 'INV-1042.pdf',
'content' => base64_encode(file_get_contents(__DIR__.'/INV-1042.pdf')),
'content_type' => 'application/pdf',
]],
]);Alle Felder finden Sie unter E-Mail senden, die Limits unter Anhänge.
Fehler behandeln
use Emailit\Exceptions\ApiErrorException;
use Emailit\Exceptions\AuthenticationException;
use Emailit\Exceptions\RateLimitException;
use Emailit\Exceptions\UnprocessableEntityException;
try {
$emailit->emails()->send($message);
} catch (AuthenticationException $e) {
// 401: the API key is missing or invalid
} catch (RateLimitException $e) {
// 429: wait and retry
} catch (UnprocessableEntityException $e) {
// 422: for example, the from domain isn't verified
} catch (ApiErrorException $e) {
error_log('Emailit error '.$e->getHttpStatus().': '.$e->getMessage());
}Ohne das SDK senden
Wenn Sie Composer nicht verwenden können, rufen Sie die API mit cURL auf:
$ch = curl_init('https://api.emailit.com/v2/emails');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('EMAILIT_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'from' => 'Acme <hello@acme.com>',
'to' => 'ada@example.com',
'subject' => 'Your receipt from Acme',
'html' => '<p>Thanks for your order.</p>',
]),
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException("Emailit returned $status: $body");
}
$email = json_decode($body, true); // $email['id'] is the em_ IDAlternativ per SMTP senden
Jede PHP-Mail-Bibliothek mit SMTP-Unterstützung funktioniert. Mit PHPMailer (composer require phpmailer/phpmailer):
use PHPMailer\PHPMailer\PHPMailer;
require __DIR__.'/vendor/autoload.php';
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host = 'smtp.emailit.com';
$mail->Port = 587;
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->SMTPAuth = true;
$mail->Username = 'emailit';
$mail->Password = getenv('EMAILIT_API_KEY');
$mail->setFrom('hello@acme.com', 'Acme');
$mail->addAddress('ada@example.com');
$mail->Subject = 'Your receipt from Acme';
$mail->isHTML(true);
$mail->Body = '<p>Thanks for your order.</p>';
$mail->AltBody = 'Thanks for your order.';
$mail->send();Mit Symfony Mailer verwenden Sie den DSN smtp://emailit:API_KEY@smtp.emailit.com:587. Für implizites TLS verwenden Sie Port 465 (PHPMailer::ENCRYPTION_SMTPS); wenn Ihr Hoster 587 blockiert, versuchen Sie 2525 oder 2587. Siehe SMTP-Einstellungen.
Webhooks empfangen
Erstellen Sie einen Webhook, der auf Ihren Endpunkt zeigt, und speichern Sie sein Signatur-Secret in EMAILIT_WEBHOOK_SECRET. Lesen Sie den unveränderten Body aus php://input und verifizieren Sie ihn, bevor Sie ihm vertrauen:
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_EMAILIT_SIGNATURE'] ?? '';
$timestamp = $_SERVER['HTTP_X_EMAILIT_TIMESTAMP'] ?? '';
$secret = getenv('EMAILIT_WEBHOOK_SECRET');
$expected = hash_hmac('sha256', $timestamp.'.'.$payload, $secret);
if (abs(time() - (int) $timestamp) > 300 || ! hash_equals($expected, $signature)) {
http_response_code(401);
exit('Invalid signature');
}
// The body is a JSON array of up to 100 events.
foreach (json_decode($payload, true) as $event) {
if ($event['type'] === 'email.bounced') {
$address = $event['data']['object']['to'];
// Stop emailing $address.
}
}
http_response_code(200);Antworten Sie innerhalb von 30 Sekunden mit einem 2xx-Status; alles andere wird wiederholt. Siehe Anfragesignatur.
Tipps für den Produktivbetrieb
- Einen Client pro Anfrage oder Worker wiederverwenden, statt für jede E-Mail einen neuen zu erstellen.
- Im Hintergrund senden. Stellen Sie Nachrichten für Massenversände in eine Warteschlange und senden Sie sie aus einem Worker, damit Seiten schnell bleiben und Sie unter Ihren Versandlimits bleiben (standardmäßig 2 E-Mails pro Sekunde).
- Wiederholungen sicher machen. Wenn Sie nach einem Timeout erneut senden, übergeben Sie mit cURL einen Header
Idempotency-Key, damit die E-Mail nicht doppelt gesendet wird. Siehe Idempotenz. - Schlüssel aus dem Web-Root fernhalten. Checken Sie nie Schlüssel oder
.env-Dateien ein und verwenden Sie pro App einen eigenen Schlüssel.