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

如何读取包含HTML、文本及图片的完整邮件正文?

如何用PHP IMAP完整读取邮件正文(含HTML、图片)

嘿,你的问题我懂了——当前脚本只抓取了邮件的纯文本部分(对应MIME结构里的1.1段),所以看不到HTML内容和图片。要完整读取所有内容,得处理邮件的MIME多部分结构,因为现代邮件通常是由多个部分组成的(纯文本、HTML、内嵌资源、附件等)。我给你整理了一套可行的方案:

核心思路

邮件的内容是按MIME类型拆分的,我们需要:

  • 递归解析邮件的每个MIME部分
  • 区分纯文本、HTML、内嵌图片(带cid:标识的资源)
  • 处理内嵌图片,把HTML里的cid:引用替换成可直接显示的内容(比如base64编码)

完整代码示例

<?php
// 连接IMAP服务器(Gmail需开启IMAP,开启2FA的话要用应用专用密码)
$msgStream = imap_open('{imap.gmail.com:993/imap/ssl/novalidate-cert}INBOX', 'abc@gmail.com', '你的登录密码/应用专用密码');
if (!$msgStream) {
    die('IMAP连接失败: ' . imap_last_error());
}

// 搜索未读邮件
$emails = imap_search($msgStream, 'UNSEEN');
if (!empty($emails)) {
    foreach ($emails as $mailNumber) {
        // 获取邮件概览信息
        $overview = imap_fetch_overview($msgStream, $mailNumber, 0);
        echo "<h3>邮件主题: " . $overview[0]->subject . "</h3>";

        // 初始化内容存储数组
        $emailContent = [
            'text' => '',
            'html' => '',
            'inline_images' => []
        ];

        // 获取邮件完整MIME结构并递归解析
        $structure = imap_fetchstructure($msgStream, $mailNumber);
        parseMimePart($msgStream, $mailNumber, $structure, $emailContent);

        // 替换HTML中的内嵌图片引用(cid转base64)
        if (!empty($emailContent['html']) && !empty($emailContent['inline_images'])) {
            foreach ($emailContent['inline_images'] as $cid => $imageData) {
                $emailContent['html'] = str_replace(
                    'cid:' . $cid,
                    'data:image/' . strtolower($imageData['type']) . ';base64,' . $imageData['content'],
                    $emailContent['html']
                );
            }
        }

        // 输出解析后的内容
        echo "<h4>纯文本内容:</h4>";
        echo "<pre>" . htmlspecialchars($emailContent['text']) . "</pre>";
        echo "<h4>HTML内容:</h4>";
        echo $emailContent['html'];

        // 保持邮件为未读状态(根据需求调整)
        imap_clearflag_full($msgStream, $mailNumber, "\\Seen");
    }
} else {
    echo "<h2>No new mail found</h2>";
}

imap_close($msgStream);

/**
 * 递归解析MIME邮件部分
 */
function parseMimePart($stream, $mailNumber, $part, &$content) {
    // 处理纯文本部分
    if ($part->type == 0) {
        $encoding = $part->encoding ?? 0;
        $text = imap_fetchbody($stream, $mailNumber, $part->number);
        $content['text'] .= decodeImapContent($text, $encoding);
    }
    // 处理HTML部分
    elseif ($part->type == 1) {
        $encoding = $part->encoding ?? 0;
        $html = imap_fetchbody($stream, $mailNumber, $part->number);
        $content['html'] .= decodeImapContent($html, $encoding);
    }
    // 处理多部分嵌套邮件(递归子部分)
    elseif ($part->type == 2) {
        foreach ($part->parts as $subPart) {
            parseMimePart($stream, $mailNumber, $subPart, $content);
        }
    }
    // 处理内嵌图片(标记为inline的附件)
    elseif ($part->type == 3 && isset($part->disposition) && strtolower($part->disposition) == 'inline') {
        // 提取图片的Content-ID(cid)
        $cid = '';
        if (isset($part->dparameters)) {
            foreach ($part->dparameters as $param) {
                if (strtolower($param->attribute) == 'filename') {
                    $cid = $param->value;
                }
            }
        }
        if (empty($cid) && isset($part->parameters)) {
            foreach ($part->parameters as $param) {
                if (strtolower($param->attribute) == 'name') {
                    $cid = $param->value;
                }
            }
        }

        // 解码图片内容并存储
        $encoding = $part->encoding ?? 0;
        $imageRaw = imap_fetchbody($stream, $mailNumber, $part->number);
        $content['inline_images'][$cid] = [
            'type' => $part->subtype,
            'content' => decodeImapContent($imageRaw, $encoding, true)
        ];
    }
}

/**
 * 解码不同编码的IMAP内容
 */
function decodeImapContent($content, $encoding, $returnBase64 = false) {
    switch ($encoding) {
        case 3: // BASE64编码
            $decoded = base64_decode($content);
            return $returnBase64 ? base64_encode($decoded) : $decoded;
        case 4: // QUOTED-PRINTABLE编码
            return quoted_printable_decode($content);
        case 0: // 7BIT
        case 1: // 8BIT
        default:
            return $content;
    }
}
?>

关键说明

  1. MIME结构解析:通过imap_fetchstructure()获取邮件的完整结构,递归遍历每个子部分,精准区分纯文本、HTML和内嵌资源。
  2. 内容解码:邮件内容常用BASE64或QUOTED-PRINTABLE编码,decodeImapContent函数统一处理解码逻辑,确保内容正常显示。
  3. 内嵌图片处理:把HTML中cid:开头的引用替换成base64编码的图片数据,这样HTML可以直接渲染图片,无需额外存储文件。
  4. Gmail配置提示:如果你的Gmail开启了两步验证,必须使用应用专用密码登录;同时要在Gmail设置中开启IMAP服务。

内容的提问来源于stack exchange,提问作者Paritosh Mahale

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:57:41