php访问gmail imap邮箱 (完美显示中文目录名与邮件)

根据官方文档以及一些网友的分享,整理编写了IMAP方式访问Gmail邮箱的代码。以便于将来会在项目中使用。

Nmsgs != 0 ) {
for( $mailno=1; $mailno<=$mboxes->Nmsgs; $mailno++ ) {

// 获取邮件内容
$email = fetchEmail($mbox, $mailno);
var_dump($email);

// 删除邮件(打上删除标记)
//imap_delete($mbox, $mailno);
}
// 删除所有打上删除标记的邮件
//imap_expunge($mbox);
}
}

/**
* 获取一封邮件的信息
* @param resource $imap_stream
* @param int $msg_number
*/
function fetchEmail($mbox , $mailno) {
// 获取邮件内容
$email = array();
// 获取Header信息
$head=imap_header($mbox, $mailno);

// 获取邮件的发件人地址
$email['from_address']=$head->from[0]->mailbox.'@'.$head->from[0]->host;

// 初始化邮件主题变量
$subject = null;
if( !empty($head->subject) ) {
// 编码转换
$mhead=imap_mime_header_decode($head->subject);
foreach( $mhead as $key=>$value) {
if( $value->charset != 'default' ) {
$subject.=mb_convert_encoding($value->text,'UTF-8',$value->charset);
}else{
$subject.=$value->text;
}
}
}

$email['subject'] = $subject;

global $charset,$htmlmsg,$plainmsg,$attachments;
$htmlmsg = $plainmsg = $charset = '';
$attachments = array();

// BODY
$s = imap_fetchstructure($mbox,$mailno);
if (!$s->parts) // simple
getpart($mbox,$mailno,$s,0); // pass 0 as part-number

else { // multipart: cycle through each part
foreach ($s->parts as $partno0=>$p)
getpart($mbox,$mailno,$p,$partno0+1);
}

$email['plainmsg'] = $plainmsg;
$email['htmlmsg'] = $htmlmsg;
$email['attachments'] = $attachments;
return $email;
}

function getpart($mbox,$mid,$p,$partno) {
// $partno = '1', '2', '2.1', '2.1.3', etc for multipart, 0 if simple
global $htmlmsg,$plainmsg,$charset,$attachments;

// DECODE DATA
$data = ($partno)? imap_fetchbody($mbox,$mid,$partno): imap_body($mbox,$mid); // simple

// PARAMETERS
// get all parameters, like charset, filenames of attachments, etc.
$params = array();
if ($p->parameters)
foreach ($p->parameters as $x)
$params[strtolower($x->attribute)] = $x->value;
if (isset($p->dparameters))
foreach ($p->dparameters as $x)
$params[strtolower($x->attribute)] = $x->value;

// ATTACHMENT
// Any part with a filename is an attachment,
// so an attached text file (type 0) is not mistaken as the message.
if (isset($params['filename']) || isset($params['name'])) {
// filename may be given as 'Filename' or 'Name' or both
$filename = ($params['filename'])? $params['filename'] : $params['name'];
// filename may be encoded, so see imap_mime_header_decode()
$attachments[$filename] = $data; // this is a problem if two files have same name
}

// TEXT
if( $p->type==0 && !empty($data) ) {
$charset = $params['charset'];
$encoding=$p->encoding;

// 根据encoding参数,进行转码
switch( $encoding ) {
case 0 :
$data=mb_convert_encoding($data, "UTF-8", $charset);
break;
case 1 :
$encode_data=imap_8bit($data);
$encode_data=imap_qprint($encode_data);
$data=mb_convert_encoding($encode_data, "UTF-8", $charset);
break;
case 3 :
$encode_data=imap_base64($data);
$data=mb_convert_encoding($encode_data, "UTF-8", $charset);
break;
case 4 :
$encode_data=imap_qprint($data);
$data=mb_convert_encoding($encode_data, 'UTF-8', $charset);
break;
case 2 :
case 5 :
default:
// 转码失败
break;
}

if (strtolower($p->subtype)=='plain') {
$plainmsg .= trim($data);

} else {
$htmlmsg .= $data;
}
}

// EMBEDDED MESSAGE
// Many bounce notifications embed the original message as type 2,
// but AOL uses type 1 (multipart), which is not handled here.
// There are no PHP functions to parse embedded messages,
// so this just appends the raw source to the main message.
if ($p->type==2 && $data) {
$plainmsg .= $data;
}

// SUBPART RECURSION
if (isset($p->parts)) {
foreach ($p->parts as $partno0=>$p2)
getpart($mbox,$mid,$p2,$partno.'.'.($partno0+1)); // 1.2, 1.2.1, etc.
}
}


发表评论 0

Your email address will not be published. Required fields are marked *