带有嵌入式图像的 IMAP PHP 未在本地主机上显示 Codeigniter
IMAP PHP with embedded images not showing Codeigniter on localhost
我使用 codeigniter 和 imap php 目前正在开发项目 xampp。由于某些原因,它们嵌入的图像未显示。
在我的 getBody() 函数中我有这个回调
$body = preg_replace_callback(
'/src="cid:(.*)">/Uims',
function($m) use($email, $uid){
//split on @
$parts = explode('@', $m[1]);
//replace local path with absolute path
$img = str_replace($parts[0], '', $parts[0]);
return "src='$img'>";
},
$body);
I get error
Question: How can I make sure it gets the images correct for the text/html body etc.
<?php
class Email extends MY_Controller {
private $enc;
private $host;
private $user;
private $pass;
private $mailbox;
private $mbox;
public function __construct() {
parent::__construct();
$this->enc = '/imap/ssl/novalidate-cert';
$this->host = '****';
$this->user = '****'; // email
$this->pass = '****'; // Pass
$this->mailbox = '{' . $this->host . $this->enc . '}';
$this->mbox = imap_open($this->mailbox, $this->user, $this->pass);
}
public function view() {
$this->data['message'] = $this->getBody($this->uri->segment(4));
$this->load->view('template/common/header', $this->data);
$this->load->view('template/common/nav', $this->data);
$this->load->view('template/mail/view', $this->data);
$this->load->view('template/common/footer', $this->data);
imap_close($this->mbox);
}
public function getBody($uid) {
$body = $this->get_part($uid, "TEXT/HTML");
// if HTML body is empty, try getting text body
if ($body == "") {
$body = $this->get_part($uid, "TEXT/PLAIN");
}
$email = $this->user;
//replace cid with full path to image
$body = preg_replace_callback(
'/src="cid:(.*)">/Uims',
function($m) use($email, $uid){
//split on @
$parts = explode('@', $m[1]);
//replace local path with absolute path
$img = str_replace($parts[0], '', $parts[0]);
return "src='$img'>";
},
$body);
return trim(utf8_encode(quoted_printable_decode($body)));
}
private function get_part($uid, $mimetype, $structure = false, $partNumber = false) {
if (!$structure) {
$structure = imap_fetchstructure($this->mbox, $uid);
}
if ($structure) {
if ($mimetype == $this->get_mime_type($structure)) {
if (!$partNumber) {
$partNumber = 1;
}
$text = imap_fetchbody($this->mbox, $uid, $partNumber, FT_PEEK);
switch ($structure->encoding) {
# 7BIT
case 0:
return imap_qprint($text);
# 8BIT
case 1:
return imap_8bit($text);
# BINARY
case 2:
return imap_binary($text);
# BASE64
case 3:
return imap_base64($text);
# QUOTED-PRINTABLE
case 4:
return quoted_printable_decode($text);
# OTHER
case 5:
return $text;
# UNKNOWN
default:
return $text;
}
}
// multipart
if ($structure->type == 1) {
foreach ($structure->parts as $index => $subStruct) {
$prefix = "";
if ($partNumber) {
$prefix = $partNumber . ".";
}
$data = $this->get_part($uid, $mimetype, $subStruct, $prefix . ($index + 1));
if ($data) {
return $data;
}
}
}
}
return false;
}
private function get_mime_type($structure) {
$primaryMimetype = array("TEXT", "MULTIPART", "MESSAGE", "APPLICATION", "AUDIO", "IMAGE", "VIDEO", "OTHER");
if ($structure->subtype) {
return $primaryMimetype[(int)$structure->type] . "/" . $structure->subtype;
}
return "TEXT/PLAIN";
}
}
简介
您正在尝试将电子邮件转换为 HTML 页面。
一封电子邮件有多个部分:
- Headers
- 基于文本的电子邮件
- HTML 基于电子邮件
- 附件
在 header 中,您会找到 Message-ID
以及其他相关元数据。
为了将电子邮件转换为网站,您必须向浏览器公开 HTML 和附件。
每个部分都有自己的 header。当您有 url='cid:Whatever'
时,您必须查找电子邮件的哪一部分具有 Content-Id header.
将电子邮件作为网页提供
您需要找到包含 HTML Body 的电子邮件部分。解析它并为你的 http://yourhost/{emailId}
替换 CID URL 你已经实现了那部分所以我不会在这里添加如何做。
在 HTML 上替换 CID URL - 实施
这是一个可能适合您的原型。
$mailHTML="<html>All your long code here</html>";
$mailId="email.eml";
$generatePartURL=function ($messgeId, $cid) {
return "http://myhost/".$messgeId."/".$cid; //Adapt this url according to your needs
};
$replace=function ($matches) use ($generatePartURL, $mailId) {
list($uri, $cid) = $matches;
return $generatePartURL($mailId, $cid);
};
$mailHTML=preg_replace_callback("/cid:([^'\" \]]*)/", $replace, $mailHTML);
按CID查找零件
http://yourhost/{emailId}/{cid}
伪代码:
- 加载电子邮件
- 按 CID 查找零件
- 使用 Base64 或其他编码解码(检查 Content-Transfer-Encoding header)
- 将文件作为 HTTP 响应提供
哪个部分有我的 CID 图片?
遍历所有电子邮件部分以查找与您的 CID 值匹配的 Content-ID header。
--_part_boundery_
Content-Type: image/jpeg; name="filename.jpg"
Content-Description: filename.jpg
Content-Disposition: inline; filename="filename.jpg"; size=39619; creation-date="Thu, 28 Dec 2017 10:53:51 GMT"; modification-date="Thu, 28 Dec 2017 10:53:51 GMT"
Content-ID: <YOUR CID WILL BE HERE>
Content-Transfer-Encoding: base64
解码传输编码并将内容作为常规 http 文件提供。
Webmail 在 PHP
中实现
RoundCube 是在 PHP 中实现的网络邮件,您可以看看他们是如何做到的:https://github.com/roundcube/roundcubemail/blob/master/program/lib/Roundcube/rcube_washtml.php
注意:我的代码不是基于此解决方案。
我使用 codeigniter 和 imap php 目前正在开发项目 xampp。由于某些原因,它们嵌入的图像未显示。
在我的 getBody() 函数中我有这个回调
$body = preg_replace_callback(
'/src="cid:(.*)">/Uims',
function($m) use($email, $uid){
//split on @
$parts = explode('@', $m[1]);
//replace local path with absolute path
$img = str_replace($parts[0], '', $parts[0]);
return "src='$img'>";
},
$body);
I get error
Question: How can I make sure it gets the images correct for the text/html body etc.
<?php
class Email extends MY_Controller {
private $enc;
private $host;
private $user;
private $pass;
private $mailbox;
private $mbox;
public function __construct() {
parent::__construct();
$this->enc = '/imap/ssl/novalidate-cert';
$this->host = '****';
$this->user = '****'; // email
$this->pass = '****'; // Pass
$this->mailbox = '{' . $this->host . $this->enc . '}';
$this->mbox = imap_open($this->mailbox, $this->user, $this->pass);
}
public function view() {
$this->data['message'] = $this->getBody($this->uri->segment(4));
$this->load->view('template/common/header', $this->data);
$this->load->view('template/common/nav', $this->data);
$this->load->view('template/mail/view', $this->data);
$this->load->view('template/common/footer', $this->data);
imap_close($this->mbox);
}
public function getBody($uid) {
$body = $this->get_part($uid, "TEXT/HTML");
// if HTML body is empty, try getting text body
if ($body == "") {
$body = $this->get_part($uid, "TEXT/PLAIN");
}
$email = $this->user;
//replace cid with full path to image
$body = preg_replace_callback(
'/src="cid:(.*)">/Uims',
function($m) use($email, $uid){
//split on @
$parts = explode('@', $m[1]);
//replace local path with absolute path
$img = str_replace($parts[0], '', $parts[0]);
return "src='$img'>";
},
$body);
return trim(utf8_encode(quoted_printable_decode($body)));
}
private function get_part($uid, $mimetype, $structure = false, $partNumber = false) {
if (!$structure) {
$structure = imap_fetchstructure($this->mbox, $uid);
}
if ($structure) {
if ($mimetype == $this->get_mime_type($structure)) {
if (!$partNumber) {
$partNumber = 1;
}
$text = imap_fetchbody($this->mbox, $uid, $partNumber, FT_PEEK);
switch ($structure->encoding) {
# 7BIT
case 0:
return imap_qprint($text);
# 8BIT
case 1:
return imap_8bit($text);
# BINARY
case 2:
return imap_binary($text);
# BASE64
case 3:
return imap_base64($text);
# QUOTED-PRINTABLE
case 4:
return quoted_printable_decode($text);
# OTHER
case 5:
return $text;
# UNKNOWN
default:
return $text;
}
}
// multipart
if ($structure->type == 1) {
foreach ($structure->parts as $index => $subStruct) {
$prefix = "";
if ($partNumber) {
$prefix = $partNumber . ".";
}
$data = $this->get_part($uid, $mimetype, $subStruct, $prefix . ($index + 1));
if ($data) {
return $data;
}
}
}
}
return false;
}
private function get_mime_type($structure) {
$primaryMimetype = array("TEXT", "MULTIPART", "MESSAGE", "APPLICATION", "AUDIO", "IMAGE", "VIDEO", "OTHER");
if ($structure->subtype) {
return $primaryMimetype[(int)$structure->type] . "/" . $structure->subtype;
}
return "TEXT/PLAIN";
}
}
简介
您正在尝试将电子邮件转换为 HTML 页面。
一封电子邮件有多个部分:
- Headers
- 基于文本的电子邮件
- HTML 基于电子邮件
- 附件
在 header 中,您会找到 Message-ID
以及其他相关元数据。
为了将电子邮件转换为网站,您必须向浏览器公开 HTML 和附件。
每个部分都有自己的 header。当您有 url='cid:Whatever'
时,您必须查找电子邮件的哪一部分具有 Content-Id header.
将电子邮件作为网页提供
您需要找到包含 HTML Body 的电子邮件部分。解析它并为你的 http://yourhost/{emailId}
替换 CID URL 你已经实现了那部分所以我不会在这里添加如何做。
在 HTML 上替换 CID URL - 实施
这是一个可能适合您的原型。
$mailHTML="<html>All your long code here</html>";
$mailId="email.eml";
$generatePartURL=function ($messgeId, $cid) {
return "http://myhost/".$messgeId."/".$cid; //Adapt this url according to your needs
};
$replace=function ($matches) use ($generatePartURL, $mailId) {
list($uri, $cid) = $matches;
return $generatePartURL($mailId, $cid);
};
$mailHTML=preg_replace_callback("/cid:([^'\" \]]*)/", $replace, $mailHTML);
按CID查找零件
http://yourhost/{emailId}/{cid}
伪代码:
- 加载电子邮件
- 按 CID 查找零件
- 使用 Base64 或其他编码解码(检查 Content-Transfer-Encoding header)
- 将文件作为 HTTP 响应提供
哪个部分有我的 CID 图片?
遍历所有电子邮件部分以查找与您的 CID 值匹配的 Content-ID header。
--_part_boundery_
Content-Type: image/jpeg; name="filename.jpg"
Content-Description: filename.jpg
Content-Disposition: inline; filename="filename.jpg"; size=39619; creation-date="Thu, 28 Dec 2017 10:53:51 GMT"; modification-date="Thu, 28 Dec 2017 10:53:51 GMT"
Content-ID: <YOUR CID WILL BE HERE>
Content-Transfer-Encoding: base64
解码传输编码并将内容作为常规 http 文件提供。
Webmail 在 PHP
中实现RoundCube 是在 PHP 中实现的网络邮件,您可以看看他们是如何做到的:https://github.com/roundcube/roundcubemail/blob/master/program/lib/Roundcube/rcube_washtml.php
注意:我的代码不是基于此解决方案。