使用garethp/php-ews无法获取邮件内嵌图片,求解决方案
解决garethp/php-ews获取邮件内嵌图片的问题
内嵌图片在Exchange Web Services中是以带ContentId的附件形式存在的,你看到的cid:image001.png@01DA1166.EB5E1980是该附件的内部引用标识,直接在外部页面无法解析。要显示这些图片,你需要获取对应附件的内容,将其转换为Base64格式的Data URI,或者保存到服务器后替换图片的src路径。
实现步骤及代码修改
获取邮件时同时请求附件数据
默认调用getItem()只返回邮件基本信息,需要显式指定获取附件字段,确保能拿到内嵌图片的内容。匹配附件与正文里的CID引用
遍历邮件附件,找到ContentId与正文img标签中cid一致的附件,将附件内容转为Base64,替换正文里的cid为Data URI。
以下是修改后的完整代码:
require_once "vendor/autoload.php"; use garethp\ews\API\Type; use garethp\ews\MailAPI; $api = MailAPI::withUsernameAndPassword('server', 'username', 'password'); $items = $api->getMailItems(); foreach ($items as $item) { if ($item instanceof Type\MessageType) { $emailId = $item->getItemId()->getId(); $subject = $item->getSubject(); echo "EmailId: " . $emailId . "<br>"; echo "Subject: " . $subject . "<br>"; // 获取邮件时同时请求附件数据 $email = $api->getItem($item->getItemId(), ['Attachments']); $bodyHtml = $email->getBody(); $attachments = $email->getAttachments() ?? []; // 遍历附件,替换正文里的CID引用 foreach ($attachments as $attachment) { if ($attachment instanceof Type\FileAttachmentType) { $contentId = $attachment->getContentId(); if (empty($contentId)) continue; // 处理CID格式,去掉尖括号(部分邮件的ContentId会带<>) $cidReference = 'cid:' . trim($contentId, '<>'); $attachmentContent = $attachment->getContent(); // 转换为Base64 Data URI $mimeType = $attachment->getContentType(); $base64Content = base64_encode($attachmentContent); $dataUri = "data:$mimeType;base64,$base64Content"; // 替换正文里的CID为Data URI $bodyHtml = str_replace($cidReference, $dataUri, $bodyHtml); } } echo "Body: " . $bodyHtml . "<br>"; } }
关键说明
- 附件类型判断:内嵌图片通常是
FileAttachmentType,且带有ContentId属性;部分邮件的ContentId会包含尖括号,需要先去除再匹配。 - Data URI格式:格式为
data:[mime类型];base64,[base64编码内容],浏览器可以直接解析显示。 - 替代方案:如果不想用Base64(大图片会导致HTML体积过大),可以将附件内容保存到服务器的静态文件目录,然后将img的src替换为该文件的访问路径,示例:
// 替换Base64部分为保存文件 $savePath = '/path/to/your/static/files/' . $attachment->getFileName(); file_put_contents($savePath, $attachmentContent); $fileUrl = '/static/files/' . $attachment->getFileName(); // 对应Web访问路径 $bodyHtml = str_replace($cidReference, $fileUrl, $bodyHtml);
内容的提问来源于stack exchange,提问作者ElPandaRojo1
相关产品推荐
相关产品推荐

