You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 17:39:04