Tutoriel
Envoyer des e-mails avec PHP
Envoyez des e-mails depuis n’importe quelle application PHP avec le SDK emailit/emailit-php, cURL ou PHPMailer via SMTP, et vérifiez les signatures des webhooks Emailit.
Ce guide explique comment envoyer des e-mails depuis une application PHP sans framework : avec le SDK officiel emailit/emailit-php, avec cURL ou via SMTP avec PHPMailer. Il présente aussi un endpoint de webhook qui vérifie les signatures. Vous utilisez Laravel ? Suivez plutôt le guide Laravel.
Prérequis
- PHP 8.1 ou version ultérieure et Composer.
- Un domaine d’envoi vérifié, par exemple
acme.com. - Une clé API. Une clé Sending Only limitée à votre domaine suffit.
- Tant que votre espace de travail n’a pas l’accès production, vous ne pouvez envoyer qu’aux adresses e-mail des comptes des membres de l’espace de travail.
Installer le SDK
composer require emailit/emailit-phpLe SDK utilise Guzzle pour les requêtes HTTP ; Composer l’installe pour vous.
Configurer votre clé API
Définissez la clé comme variable d’environnement dans votre serveur web, votre pool PHP-FPM ou votre panneau d’hébergement, et lisez-la à l’exécution :
export EMAILIT_API_KEY=secret_••••••••••••••••••••••••••••••••$apiKey = getenv('EMAILIT_API_KEY');Si vous chargez un fichier .env avec un paquet comme vlucas/phpdotenv, gardez ce fichier hors de la racine web et hors du contrôle de version.
Envoyer un e-mail
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_…Le même appel accepte cc, bcc, reply_to, attachments, template avec variables, scheduled_at et tracking. Pour joindre un fichier, encodez-le en 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',
]],
]);Pour tous les champs, consultez Envoyer un e-mail ; pour les limites, consultez Pièces jointes.
Gérer les erreurs
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());
}Envoyer sans le SDK
Si vous ne pouvez pas utiliser Composer, appelez l’API avec cURL :
$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_ IDEnvoyer plutôt via SMTP
Toute bibliothèque d’e-mail PHP compatible SMTP fonctionne. Avec 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();Avec Symfony Mailer, utilisez le DSN smtp://emailit:API_KEY@smtp.emailit.com:587. Pour le TLS implicite, utilisez le port 465 (PHPMailer::ENCRYPTION_SMTPS) ; si votre hébergeur bloque le port 587, essayez 2525 ou 2587. Consultez Paramètres SMTP.
Recevoir des webhooks
Créez un webhook qui pointe vers votre endpoint et enregistrez son secret de signature dans EMAILIT_WEBHOOK_SECRET. Lisez le corps brut depuis php://input et vérifiez-le avant de vous y fier :
$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);Répondez dans les 30 secondes avec un 2xx ; pour toute autre réponse, Emailit réessaie. Consultez Signature des requêtes.
Conseils pour la production
- Réutilisez un seul client par requête ou par worker au lieu d’en créer un par e-mail.
- Envoyez en arrière-plan. Pour les envois en masse, placez les messages dans une file d’attente et envoyez-les depuis un worker : vos pages restent rapides et vous restez sous vos limites d’envoi (2 e-mails par seconde par défaut).
- Sécurisez les relances. Si vous relancez une requête après un timeout, envoyez un en-tête
Idempotency-Keyavec cURL pour que l’e-mail ne soit pas envoyé deux fois. Consultez Idempotence. - Gardez les clés hors de la racine web. Ne commitez jamais de clés ni de fichiers
.env, et utilisez une clé distincte par application.