使用SendGrid发送多封邮件时如何按收件人切换contentType?
问题分析与解决方案
你遇到的错误是因为同一个SendGrid邮件实例里重复添加了内容块。SendGrid的API规则明确:text/plain和text/html类型的内容各自只能存在一个,既不能重复添加同类型内容,也不能在循环中反复给同一个邮件对象追加不同格式的内容。
你的代码逻辑是复用同一个$mail对象循环处理收件人,每次循环都调用addContent(),导致邮件实例里的内容块越积越多,触发了API的校验规则。
要实现「给不同收件人发送不同格式的邮件」,正确的做法是为每个收件人创建独立的邮件实例,具体修改如下:
foreach ($emailAddress as $key => $email) { // 每个收件人都新建一个邮件对象 $mail = new Mail(); // 补充你的发件人信息 $mail->setFrom(new From('your-sender@domain.com', 'Sender Name')); $mail->setSubject($subject); $personalization = new Personalization(); $personalization->addTo(new To(trim($email))); $mail->addPersonalization($personalization); // 根据收件人设置对应格式的内容 if ($email == "example@example.org" || $email == "example2@example2.org") { $mail->addContent( "text/plain", str_replace(" ", "", $messagePlain) ); } else { $mail->addContent( "text/html", nl2br($message) ); } // 发送当前邮件 $sendgrid = new SendGrid('你的SendGrid API密钥'); try { $response = $sendgrid->send($mail); // 可添加发送成功后的逻辑,比如记录日志 } catch (Exception $e) { // 处理发送失败的情况 echo '发送失败: ' . $e->getMessage(); } }
优化方案:批量发送减少API调用
如果想避免循环中多次调用SendGrid API,可以用批量发送功能,将多个邮件实例打包成一个请求发送:
$sendgrid = new SendGrid('你的SendGrid API密钥'); $mails = []; foreach ($emailAddress as $key => $email) { $mail = new Mail(); $mail->setFrom(new From('your-sender@domain.com', 'Sender Name')); $mail->setSubject($subject); $personalization = new Personalization(); $personalization->addTo(new To(trim($email))); $mail->addPersonalization($personalization); if ($email == "example@example.org" || $email == "example2@example2.org") { $mail->addContent("text/plain", str_replace(" ", "", $messagePlain)); } else { $mail->addContent("text/html", nl2br($message)); } $mails[] = $mail; } // 批量发送 try { $response = $sendgrid->sendMultiple($mails); } catch (Exception $e) { echo '批量发送失败: ' . $e->getMessage(); }
内容的提问来源于stack exchange,提问作者Freedi
相关产品推荐
相关产品推荐

