如何使用SendGrid API解决PHP发送邮件内联图片变附件问题
问题原因&解决方案
导致inline图片显示为附件的核心问题有3个,按优先级修复即可:
- 参数顺序错误:SendGrid PHP库
Attachment类构造函数的参数顺序为内容, MIME类型, 文件名, 展示类型, content_id,你当前代码把「文件名」和「MIME类型」的顺序写反了,导致inline属性和content_id没有被正确识别,这是最核心的问题。 - 图片内容没有正确编码:你当前传的图片内容是占位字符串(比如
base64 encoded content2、content3),没有填入真实的图片base64编码内容,客户端无法正常解析图片。 - HTML正文缺少cid引用:内联图片必须在邮件的HTML内容中通过
<img src="cid:对应content_id">的格式引用,没有引用的inline附件会被邮件客户端自动判定为普通附件。
注意:读取图片时建议使用绝对路径避免文件读取失败,传入
Attachment的base64内容不需要加data:image/xxx;base64,前缀,SendGrid会自动处理格式。
修复后的代码示例
<?php // Load Composer's autoloader require_once __DIR__.'/../vendor/autoload.php'; use SendGrid\Mail\Attachment; use SendGrid\Mail\Mail; function sendEmail($tos, $subject, $html) { $email = new \SendGrid\Mail\Mail(); $email->setFrom("hi@pandascrow.io", "Pandascrow"); $email->setSubject($subject); // 这里你写死了tos,实际可以换成传入的$tos参数,按自己需求调整 $tos = [ "tom***@gmail.com" => "Precious Tom", "jamb***@gmail.com" => "Jamb Tom" ]; $email->addTos($tos); $email->addContent("text/html", $html); // 封装读取图片并转base64的工具方法 function getImageBase64(string $path): string { $imageContent = file_get_contents($path); return base64_encode($imageContent); } $attachments = [ new Attachment( getImageBase64(__DIR__ . '/../../logo.png'), // 真实图片base64内容 "image/png", // 第二个参数是MIME类型 "logo.png", // 第三个参数是文件名 "inline", // 第四个参数是展示类型 "logo" // 第五个参数是content_id,对应HTML里cid:logo ), new Attachment( getImageBase64(__DIR__ . '/../../assets/img/social-icons/twitter.png'), "image/png", "twitter.png", "inline", "twitter" ), new Attachment( getImageBase64(__DIR__ . '/../../assets/img/social-icons/linkedin.png'), "image/png", "linkedin.png", "inline", "linkedin" ), new Attachment( getImageBase64(__DIR__ . '/../../assets/img/social-icons/instagram.png'), "image/png", "instagram.png", "inline", "instagram" ) ]; $email->addAttachments($attachments); $sendgrid = new \SendGrid(SENDGRID_API_KEY); try { $response = $sendgrid->send($email); return ($response->statusCode() == 202) ? 200 : $response->statusCode(); } catch (Exception $e) { return 'Caught exception: '. $e->getMessage(); } } ?>
HTML正文引用示例
要在邮件正文里显示对应的图片,直接在HTML代码对应位置插入以下标签即可:
<!-- 显示logo图片 --> <img src="cid:logo" alt="Pandascrow Logo"> <!-- 显示twitter图标 --> <img src="cid:twitter" alt="Twitter"> <!-- 其他图片同理替换cid后的名称即可 -->
内容的提问来源于stack exchange,提问作者Precious Tom
相关产品推荐
相关产品推荐

