PHP邮件专题
PHP SMTP类
/***********************************
PHP MIMESMTP ver 1.0 Powered by Boss_ch, Unigenius soft ware co. Ltd
All rights reserved, Copyright 2000 ;
本类用PHP通过smtp sock 操作发送MIME 类型的邮件,可以发送
HTML 格式的正文、附件,采用base64 编码
本版本是针对个人的发送,与多人群发版本不同的是,每发送到一个人,就重新进行一次编码,在接收端的用户看来,只是发送给他一个人的。
针对多人群发的情况,只发送一次,通过多个RCPTTO命令发送到不同的人信箱中,
说明:
请把$hostname 设为你有权限的默认smtp 服务器或是在new 时指定
把$charset 改成你的默认字符集
Html 正文中如有图片,请用绝对路径的引用"httP://host/path/image.gif";
并连上网,以保证程序能读取到图片的数据信息
如果是通过表单提交过来的Html 正文,请先用StripSlashes($html_body)把正文内容进行预处理
Html 中用到的样式表文件,请不要用
之类的引用,直接把样式表定义放在
标签中
转载请保留此版权信息,Bugs Report : [email]boss_ch@china.com[/email]
*************************************/
if(!isset($__smtp_class__)){
$__smtp_class__=1;
class smtp
{
var $hostname="";
var $port=25;
var $connection=0;
var $debug=1;
var $timeout=30;
var $err_str;
var $err_no;
var $autocode=true;
var $charset="??????";
var $subject="";
var $body="";
var $attach="";
var $temp_text_body;
var $temp_html_body;
var $temp_body_images;
var $bound_begin="=====powered_by_boss_chen_";
var $bound_end="_046484063883_=====";
Function smtp($server="smtp.china.com",$port=25,$time_out=20)
{$this->hostname=$server;
$this->port=$port;
$this->timeout=$time_out;
return true;
}
Function outdebug($message)
{
echo htmlspecialchars($message)."
n";
}
function command($command,$return_lenth=1,$return_code='2')
{
if ($this->connection==0)
{
$this->err_str="没有连接到任何服务器,请检查网络连接";
return false;
}
if ($this->debug)
$this->outdebug(">>> $command");
if (!fputs($this->connection,"$command rn"))
{
$this->err_str="无法发送命令".$command;
return false;
}
else
{
$resp=fgets($this->connection,256);
if($this->debug)
$this->outdebug("$resp");
if (substr($resp,0,$return_lenth)!=$return_code)
{
$this->err_str=$command." 命令服务器返回无效:".$resp;
return false;
}
else
return true;
}
}
Function open()
{
if($this->hostname=="")
{$this->err_str="无效的主机名!!";
return false;
}
if ($this->debug) echo "$this->hostname,$this->port,&$err_no, &$err_str, $this->timeout
";
if (!$this->connection=fsockopen($this->hostname,$this->port,&$err_no, &$err_str, $this->timeout))
{
$this->err_str="连接到SMTP 服务器失败,错误信息:".$err_str."错误号:".$err_no;
return false;
}
else
{
$resp=fgets($this->connection,256);
if($this->debug)
$this->outdebug("$resp");
if (substr($resp,0,1)!="2")
{$this->err_str="服务器返回无效的信息:".$resp."请检查SMTP服务器是否正确";
return false;
}
return true;
}
}
Function Close()
{
if($this->connection!=0)
{
fclose($this->connection);
$this->connection=0;
}
}
Function Buildhead($from_name,$to_name,$from_mail,$to_mail,$subject)
{
if (empty($from_name))
$from_name=$from_mail;
if (empty($to_name)) $to_name=$to_mail;
$this->subject="From: =?$this->charset?B?".base64_encode($from_name)."?=rn";
$this->subject.="To: =?$this->charset?B?".base64_encode($to_name)."?=rn";
$subject=ereg_replace("n","",$subject);
$this->subject.="Subject: =?$this->charset?B?".base64_encode($subject)."?=rn";
if ($this->debug) echo nl2br(htmlspecialchars($this->subject));
return true;
}
函数 parse_html_body($html_body=null)
{
$passed="";
$image_count=0;
$this->temp_body_images=array() ;
while (eregi("] )src[[:space:]]*=[[:space:]]*([^ ] )",$html_body,$reg))
{
$pos=@strpos($html_body,$reg[0]);
$passed.=substr($html_body,0,$pos);
$html_body=substr($html_body ,$pos strlen($reg[0]));
$image_tag=$reg[2];
$image_att=$reg[1];
$tag_len=strlen($image_tag);
if ($image_tag[0]=="'" 或 $image_tag[0]=='"')
$image_tag=substr($image_tag,1);
if (substr($image_tag, strlen($imgage_tag)-1,1)=="'" 或 substr($image_tag,strlen($imgage_tag)-1,1)=='"')
$image_tag=substr($image_tag,0, strlen($imgage_tag)-1);
//回显$image_tag."
";
$cid=md5(uniqid(rand()));
$cid=substr($cid ,0,15)."@unigenius.com";
$passed.="
$end_pos=@ strpos($html_body,'>');
$passed.=substr($html_body,0,$end_pos);
$html_body=substr($html_body,$end_pos);
//把图片数据读取出来保存到一个数据;
$img_file_con=fopen($image_tag,"r");
unset($image_data);
while ($tem_buffer=AddSlashes(fread($img_file_con) ,16777216)))
$image_data.=$tem_buffer;
fclose($img_file_con);
$image_exe_name=substr($image_tag,strrpos($image_tag,'.') 1,3);
switch (strtolower($image_exe_name))
{
case "jpg":
case "jpeg":
$content_type="image/jpeg";
break;
case "gif":
$content_type="image/gif";
break;
case "png":
$content_type="image/x-png";
break;
案例“tif”:
$content_type="image/tif";
break;
默认:
$content_type="image/";
break;
}
$this->temp_body_images[$image_count][name]=basename($image_tag);
$this->temp_body_images[$image_count][type]=$content_type;
$this-> temp_body_images[$image_count][cid]=$cid;
$this->temp_body_images[$image_count][data]=$image_data;
$image_count ;
}
$this->temp_html_body= $passed.$html_body;
返回 true;
}
function build_content($bound_level=0,$text_body,$html_body,$hava_att=false)
{
if ($html_body)
{
if (eregi("{
$bound_level ;
if ($text_body)
{
$this->body.="内容类型:多部分/相关;
type="multipart/alternative";
tboundary="";
$this->body.=$this->bound_begin.$bound_level.$this->bound_end.""rnrn";
}
其他
{
$this->body.="Content-Type: 多部分/相关;
tboundary="";
$this->body.=$ this->bound_begin.$bound_level.$this->bound_end.""rnrn";
}//对于是否text正文、html正文有没有,须有不同的MIME头
if (! $hava_att) $this->body.="This is a multi-part message in MIME format.rnrn";
// 正文标识,如果是已经有附件的编码,则在正文中不需要这一句
$this->body.="--".$this->bound_begin.$bound_level.$this->bound_end."rn";
$this->parse_html_body($html_body);
if ($text_body)
{
$this->body.="Content-Type: multipart/alternative;
tboundary="";
$bound_level ;
$this->body. =$this->bound_begin.$bound_level.$this->bound_end.""rnrn";
$this->body.="--".$this->bound_begin.$bound_level.$this->bound_end ."rn";
$this->body.="Content-Type: text/plain;rn";
$this->body.="tcharset="$this->charset"rn";
$this->body.="Content-Transfer-Encoding: base64rn";
$this->body.="rn".chunk_split(base64_encode(StripSlashes($text_body)))."rn";
$this->body.="--".$this->bound_begin.$bound_level.$this->bound_end."rn";
$this->body.="内容类型:文本/html;rn";
$this->body.="tcharset="$this->charset"rn";
$this->body.="内容传输编码:base64rn";
$this->body.="rn".chunk_split(base64_encode(StripSlashes($this->temp_html_body)))."rn";
$this->body.="--".$this- >bound_begin.$bound_level.$this->bound_end."--rnrn";
$bound_level--;
}
else
{
$this->body.="- -".$this->bound_begin.$bound_level.$this->bound_end."rn";
$this->body.="Content-Type: text/html;rn";
$this- >body.="tcharset="$this->charset"rn";
$this->body.="Content-Transfer-Encoding: base64rn";
$this->body.="rn" .chunk_split(base64_encode(StripSlashes($this->temp_html_body)))."rn";
}//正文编码,有或没有文本部分,编成不同的格式。
for ($i=0;$i
temp_body_images);$i ) { $this->body.="--".$this->bound_begin.$bound_level.$ this->bound_end."rn"; $this->body.="Content-Type:".$this->temp_body_images[$i][type]."; name=""; $this->body.=$this->temp_body_images[$i][name].""rn"; $this->body.="Content-Transfer-Encoding: base64rn"; $this->body.="Content-ID: temp_body_images[$i][cid].">rn"; $this->body.="rn".chunk_split(base64_encode(StripSlashes($ this->temp_body_images[$i][数据])))."rn"; } $this->body.="--".$this->bound_begin.$bound_level.$this- >bound_end."--rnrn"; $bound_level--; } else // 有或没有图片,上面是有图片的处理,下面是没有图片的处理 { $this->temp_html_body=$html_body; if ($text_body) { $bound_level ; $this->body.="内容类型:多部分/替代; tboundary=""; $this->body.=$this->bound_begin.$bound_level.$this->bound_end.""rnrn"; if (!$hava_att) $this ->body.="rn这是一条 MIME 格式的多部分消息。rnrn"; $this->body.="--".$this->bound_begin.$bound_level.$this->bound_end。 "rn"; $this->body.="Content-Type: text/plain;rn"; $this->body.="tcharset="$this->charset"rn"; $this->body.="Content-Transfer-Encoding: base64rn"; $this->body.="rn".chunk_split(base64_encode(StripSlashes($text_body)))."rn"; $this->body.="--".$this->bound_begin.$bound_level.$this->bound_end."rn"; $this->body.="Content-Type: text/ html;rn"; $this->body.="tcharset="$this->charset"rn"; $this->body.="内容传输编码:base64rn"; $this->body.="rn".chunk_split(base64_encode(StripSlashes($this->temp_html_body)))."rn"; $this->body.="--".$this-> bound_begin.$bound_level.$this->bound_end."--rnrn"; $bound_level--; } else { $this->body.="Content-类型:text/html;rn"; $this->body.="tcharset="$this->charset"rn"; $this->body.="内容传输编码:base64rn "; $this->body.="rn".chunk_split(base64_encode(StripSlashes($this->temp_html_body)))."rn"; }//正文编码,有或没有文本部分,编成不同的格式。 }// end else } else // 如果没有html 正文,只有text 正文 { $this->body.="Content-Type: text/plain; tcharset="$this->charset"rn"; $this->body.="Content-Transfer-Encoding: base64rn"; $this->body.="rn".chunk_split(base64_encode(StripSlashes($text_body)))."rn"; } }// end function default Function Buildbody($text_body=null,$html_body=null,$att=null) { $this->body="MIME-Version: 1.0rn"; if (null==$att or (@count($att)==0)) //如果没有附件,查看正文的类型; { $encode_level=0; $this->build_content($encode_level,$text_body,$html_body); }// 如果没有附件, // ******************************************************** else //如果有附件, { $bound_level=0; $this->body.="Content-Type: multipart/mixed; tboundary=""; $bound_level ; $this->body.=$this->bound_begin.$bound_level.$this->bound_end.""rnrn"; $this->body.="This is a multi-part message in MIME format.rnrn"; $this->body.="--".$this->bound_begin.$bound_level.$this->bound_end."rn"; $this->build_content($bound_level,$text_body,$html_body,true);// 编入正文部分 $num=count($att); for ($i=0;$i{ $file_name=$att[$i][name]; $file_source=$att[$i][source]; $file_type=$att[$i][type]; $file_size=$att[$i][size]; if (file_exists($file_source)) { $file_data=addslashes(fread($fp=fopen($file_source,"r"), filesize($file_source))); $file_data=chunk_split(base64_encode(StripSlashes($file_data))); $this->body.="--".$this->bound_begin.$bound_level.$this->bound_end."rn"; $this->body.="Content-Type: $file_type;rntname="$file_name"rnContent-Transfer-Encoding: base64rn"; $this->body.="Content-Disposition: attachment;rntfilename="$file_name"rnrn"; $this->body.=$file_data."rn"; } }//end for $this->body.="--".$this->bound_begin.$bound_level.$this->bound_end."--rnrn"; }// end else if ($this->debug) echo nl2br(htmlspecialchars($this->body)); return true; } function send($from_name,$to_name,$from_mail,$to_mail,$subject,$text_body=false,$html_body=false,$att=false) { if (empty($from_mail) or empty($to_mail)) { $this->err_str="没有指定正确的邮件地址:发送人:".$from_mail."接收人:".$to_mail; return false; } if (gettype($to_mail)!="array") $to_mail=split(",",$to_mail);//如果不是数组,转换成数组,哪怕只有一个发送对象; if (gettype($to_name)!="array") $to_name=split(",",$to_name);//如果不是数组,转换成数组,哪怕只有一个发送对象; $this->Buildbody($text_body,$html_body,$att); // 所有信件的内容是一样的,可以只编一次,而对于不同的收信人,需要不同的Head if (!$this->open()) return false; if (!$this->command("HELO $this->hostname",3,"250")) return false; // 与服务器建立链接 if (!$this->open()) return false; if (!$this->command("HELO $this->hostname",3,"250")) return false; for ($i=0;$i{ $this->Buildhead($from_name,$to_name[$i],$from_mail,$to_mail[$i],$subject); if (!$this->command("RSET",3,"250")) return false; if (!$this->command("MAIL FROM:".$from_mail,3,"250")) return false; if (!$this->command("RCPT TO:".$to_mail[$i],3,"250")) return false; if (!$this->command("DATA",3,"354")) return false; // 准备发送邮件 if ($this->debug) $this->outdebug("sending subject;"); if (!fputs($this->connection,$this->subject)) {$this->err_str="发送邮件头时出错!";return false;} if ($this->debug) $this->outdebug("sending body;"); if (!fputs($this->connection,$this->body)) {$this->err_str="发送正文时出错!";return false;} if (!fputs($this->connection,".rn")) {$this->err_str="发送正文时出错!";return false;}//正文发送完毕,退出; $resp=fgets($this->connection,256); if($this->debug) $this->outdebug("$resp"); if (substr($resp,0,1)!="2") { $this->err_str="发送完后,服务器没有响应!!"; return false; } //发送邮件 } if (!$this->command("QUIT",3,"221")) return false; $this->close(); return true; } }//结束类定义 }//结束 if(!isset($__smtp_class__)) ?> PHP SMTP 类使用方法 include("smtp.php"); $mail = new smtp("localhost") ; $mail->debug = 0; $sender_name = "root"; $sender_mail = "root@localhost"; $to_name = "mm"; $to_mail = "[email]mm@your.com[/email]"; $subject = "我想你"; $content = "我很想你。"; $att[0]["name"] = "miss.jpg"; $att[0]["source"] = "/path/to/your/miss.jpg"; $att[ 0]["type"] = "image/jpeg"; $att[0]["size"] = "10kb"; $extra_subject = "收件人:".$to_mail." 主题:".$subject; if (!$mail->send($sender_name,$to_name,$sender_mail,$to_mail,$extra_subject,$content,false,$att)) $ err = 1; ?> 返回文件的MIME类型的函数guessMIMEType() functionguessMIMEType($filename) { //GUESS MIME 类型 $filename = basename($filename); if(strrchr($filename,".") == false) { return("application/octet-stream"); } $ext = strrchr($filename,"."); switch($ext) { case ".gif": return "image/gif"; break; case ".gz": return "application/x-gzip"; case ".htm": case ".html": return "text/html "; break; case ".jpg": return "image/jpeg"; break; case ".tar": return "application/x-tar "; break; case ".txt": 返回 "text/plain"; break; case ".zip": 返回 "application/zip"; break; 默认: return "application/octet-stream"; break; } } 检测Email地址的函数IsValidEmail () function IsValidEmail($Email) { if(!ereg("^[[:alnum:]_.] @([[:alnum:]_] .) [[:alnum:]] [[:alnum:]][[:alnum:]]?$",$Email, $regs)){ $IsValidEmail = false; } 其他 { $ IsValidEmail = true; } return $IsValidEmail; } 一个MIME MAIL类,请大家注意如何构造一个邮件体 class mime_mail { var $parts; var $to; var $from; var $headers; var $subject; var $body; /* * void mime_mail() * 类构造函数 */ function mime_mail() { $this->parts = array() ; $this->to = ""; $this->from = ""; $this->subject = ""; $this->body = ""; $this->headers = ""; } /* * void add_attachment(string message, [string name], [string ctype]) * 添加附件到邮件对象 */ function add_attachment($message, $name = "", $ctype = "application/octet-stream") { $this->parts[] = array ( "ctype" => $ ctype, "message" => $message, "encode" => $encode, "name" => $name ); } /* * void build_message(array part= * 构建多部分邮件的消息部分 */ function build_message($part) { $message = $part["message"] $message = chunk_split(base64_encode($message)); $encoding = "base64"; .$part["ctype"]. ($part["name"]?";ntname="".$part["name"].""" : ""). "nContent-传输编码:$encoding". "nContent-Disposition:附件". ($part["name"]?";ntfilename="".$part["name"].""" : ""). "nn$messagen"; } /* * void build_multipart() * 构建多部分邮件 */ 函数build_multipart() { $boundary = "b".md5(uniqid(time())); $multipart = "Content-Type: multipart/mixed;ntboundary="$boundary"nn这是MIME 编码的消息.nn--$boundary"; for($i = sizeof($this->parts)-1; $i >= 0; $i--) { $multipart .= "n".$this->build_message($this->parts[$i])."--$boundary"; } return $multipart.= "--n "; } /* * void send() * 发送邮件(最后调用的类函数) */ function send() { $addtionheaders = ""; if (!empty($this->from)) $addtionheaders .= "来自: ".$this->from."n"; if (!empty($this->headers)) $addtionheaders .= $this->headers."n"; if (!empty($this->body)) $this->add_attachment($this->body, "", "text/plain"); $ addtionheaders .= "MIME-版本: 1.0n".$this->build_multipart(); $fp = fopen("mail.txt","w"); fputs($fp, $addtionheaders); fclose($fp); 邮件($this->to, $this->subject, "", $addtionheaders); } }; // 课程结束 /* * 用法示例 * $attachment = fread(fopen("test.jpg", "r"), filesize("测试.jpg")); $mail = new mime_mail(); $mail->from = "[email]foo@bar.com[/email]"; $mail->headers = "错误-收件人: [email]foo@bar.com[/email]"; $mail->to = "[email]bar@foo.com[/email]"; $mail->subject = "测试..."; $mail->body = "这只是一个测试。"; $mail->add_attachment("$attachment", "test.jpg", "image/jpeg"); $mail->send(); */ ?> myimap类,读取邮件 ////////////// ///////////////////////////////// //起源由 Alpha.Z (5/21/2000) //由 Belltree 修改 (11/01/2000) ////////////////////////////// ////////////////// class myimap { var $username=""; var $userpwd=""; var $hostname=""; var $port=0; var $connection=0; // 是否连接 var $state="DISCONNECTED"; // 连接状态 var $greeting=""; var $must_update=0; var $inStream=0; var $num_msg_parts = 0; var $attach; var $num_of_attach = 0; function open() { if ($this->port==110) $this->inStream=imap_open("{". $this->主机名."/pop3:110}收件箱",$this->用户名,$this->userpwd); else $this->inStream=imap_open("{".$this- >主机名.":143}INBOX",$this->用户名,$this->userpwd); if ($this->inStream) { //echo "用户: $this->用户名的信箱连接成功。 "; return $inStream; } else { echo "用户:$this->用户名的信箱连接失败 "; return 0; } } 函数 close() { if(imap_close($this->inStream)) { //echo " 已经与服务器$this->主机名断开连接。"; return 1; } else { //echo " 与服务器$this->主机名断开连接失败。"; return 0; } } function DeleteMail($msg_no){ if ( @imap_delete($this->inStream,$msg_no)) 返回 true; else 返回 false; } function ExpungeMail(){ if (@imap_expunge($this->inStream)) 返回 true; else 返回 false; } function CheckMailbox($page_size,$page) { $mboxinfo=@imap_mailboxmsginfo($this->inStream); //$mboxinfo=imap_check($this ->inStream); if ($mboxinfo) if ($mboxinfo->Nmsgs>0) { //echo "您邮箱:".$mboxinfo->邮箱." "; echo $this->用户名."@wells.com 的收件箱里共有邮件数:".$mboxinfo->Nmsgs." n"; echo "未读邮件数:".$mboxinfo->未读。""; echo "新邮件数:".$mboxinfo->最近。""; echo "总占用空间:".$mboxinfo->大小." 字节 n"; $last_page = ceil($mboxinfo->Nmsgs/$page_size); $cur_page = $第 1 页; $num_page = $last_page; echo "第".$cur_page."页,共".$last_page."页。
"; } else { echo "您的信箱里没有邮件。 n"; } else { echo '错误:无法获取收件箱的信息。 '; return 0; } echo "n";n"; echo "
状态
发件人
主题
时间
大小
n"; $sortby="SORTDATE"; $sort_reverse=1; $sorted = imap_sort($this->inStream, $sortby, $sort_reverse, SE_UID); for ($i=0;$iNmsgs;$i ) { if (($i>=$page*$page_size) and ($i$msg_no = @imap_msgno($this->inStream, $sorted[$i]); $msgHeader = @imap_header($this->inStream, $msg_no); //日期 if (isset($msgHeader->date)) { $date = $msgHeader->date; if (ord($date) > 64) $date = substr($date, 5); $datepart = split(" ",$date); $date = $datepart[0]." ".$datepart[1]." ".$datepart[2]." ".$datepart[3]; /* while (strstr(' ', $date)) { $date = str_replace(' ', ' ', $date); } */ } if (isset($msgHeader->from[0])) { $from = $msgHeader->from[0]; if (isset($from->personal)) { $frm = trim($this->decode_mime_string($from->personal)); if (isset($from->mailbox) && isset($from->host)) { $frm_add = $from->mailbox . '@' . $from->host; } } else if (isset($from->mailbox) && isset($from->host)) { $frm = $from->mailbox . '@' . $from->host; } else if (isset($msgHeader->fromaddress)) $frm = trim($h->fromaddress); } else if (isset($msgHeader->fromaddress)) $frm = trim($msgHeader->fromaddress); if (isset($msgHeader->toaddress)) $to = trim($msgHeader->toaddress); else $to = "未知"; if (isset($msgHeader->subject)) $sub = trim($this->decode_mime_string($msgHeader->subject)); if ($sub == "") $sub = "无主题"; if (isset($msgHeader->Size)) $msg_size = ($msgHeader->Size > 1024) ? sprintf("%.0f kb", $msgHeader->Size / 1024) : $msgHeader->Size; //if (strlen($frm) > 50) // $frm = substr($frm, 0, 50) . '...'; if (strlen($sub) > 50) $sub = substr($sub, 0, 50) . '...'; if ($msgHeader->Unseen == "U") $newmail = "未读"; else $newmail = "已读"; echo "n"; echo "$newmail
n"; echo ''.$frm.'
'.$sub.'
'.$date.'
'.$msg_size.' '; echo " n"; }} echo "
echo "
状态
发件人 主题
时间
大小
n"; $sortby="SORTDATE";n"; if ($page == 0) echo "第一页 n"; else echo "第一页 n"; if (($prev_page = $page-1) echo "前一页 n"; else echo "前一页 n"; if (($next_page = $page 1) >= $last_page) echo "后一页 n"; else echo "后一页 n"; $last_page --; if ( $last_page echo "最末页 n"; else echo "最末页 n"; echo "
$sort_reverse=1;$sorted = imap_sort($this->inStream, $sortby, $sort_reverse, SE_UID);for ($i=0;$iNmsgs;$i ) {if (($i>=$page*$page_size) and ($i$msg_no = @imap_msgno($this->inStream, $sorted[ $i]);$msgHeader = @imap_header($this->inStream, $msg_no);//日期if (isset($msgHeader->date)) {$date = $msgHeader->date;if (ord($date) > 64)$date = substr($date, 5);$ datepart = split(" ",$date);$date = $datepart[0]." ".$datepart[1]." ".$datepart[2]." ".$datepart[3]; /*while (strstr(' ', $date)){$date = str_replace(' ', ' ', $date);}*/ }if (isset($msgHeader->from[0])){$from = $msgHeader->from[0];if (isset( $from->个人)){$frm = trim($this->decode_mime_string($from->个人));if (isset($from->邮箱) && isset($ from->host)){$frm_add = $from->邮箱 . '@'。 $from->host;}}elseif (isset($from->邮箱) && isset($from->host)){$frm = $from->邮箱 . '@'。 $from->host;}elseif (isset($msgHeader->fromaddress))$frm = trim($h->fromaddress);} elseif (isset($msgHeader->fromaddress))$frm = trim($msgHeader->fromaddress);if (isset($msgHeader->toaddress)) $to = trim($msgHeader->toaddress);else$to = "未知";if (isset($msgHeader->subject))$ sub = trim($this->decode_mime_string($msgHeader->subject));if ($sub == "")$sub = "无主题"; if (isset($msgHeader->Size))$msg_size = ($msgHeader->Size > 1024) ? sprintf("%.0f kb", $msgHeader->Size / 1024) : $msgHeader->Size;//if (strlen($frm) > 50)// $frm = substr($ frm, 0, 50) 。 '...';if (strlen($sub) > 50)$sub = substr($sub, 0, 50) 。 '...';if ($msgHeader->Unseen == "U")$newmail = "未读";else$newmail = "已读";echo "n";echo "$newmailn";echo '' .$frm.'
'.$sub.'
'.$date.'
'.$msg_size.' ';回显“
n”;}}回显"
n";echo "n";if ($page == 0)echo "第一页 n";elseecho "第一页 n";if (($prev_page = $page-1) echo "前一页 n";elseecho "前一页 n";if (($next_page = $page 1) >= $last_page )echo "后一页 n";elseecho "后一页 n";$last_page --;if ( $last_page echo "最末页 n"; elseecho "最末页 n";echo "
n"; } 函数decode_mime_string ($string) { $pos = strpos($string, '=?'); if (!is_int($pos) )) { return $string; } $preceding = substr($string, 0, $pos); // 保存任何前面的文本 $ search = substr($string, $pos 2, 75); // mime 标头规范规定这是单个编码单词的最长长度 $d1 = strpos($search, '?'); if (!is_int($d1)) { return $string; } $charset = substr($string, $pos 2, $d1); $ search = substr($search, $d1 1); $d2 = strpos($search, '?'); if (!is_int($d2)) { 返回 $string; } $encoding = substr($search, 0, $d2); $search = substr($search, $d2 1); $end = strpos($search, '?='); if (!is_int($end)) { return $string; } $encoded_text = substr($search, 0, $end); $rest = substr($string, (strlen($preceding . $charset . $encoding . $encoded_text) 6)); switch ($编码) { case 'Q': case 'q': $encoded_text = str_replace('_', ' ', $encoded_text); $encoded_text = str_replace(' =', '%', $encoded_text); $decoded = urldecode($encoded_text); break; case 'B': case 'b': $decoded = urldecode(base64_decode($encoded_text)); break; 默认: $decoded = '=?' '?' '?' . $encoded_text . '?='; break; } 返回 $decoded . $this->decode_mime_string($rest); } 函数display_toaddress ($user, $server, $from) { return is_int(strpos($from, $this->get_barefrom($user, $server))); } 函数 get_barefrom($user, $server) { $barefrom = "$user@$real_server"; return $barefrom; } Function get_struct($msg_num) { $struct=imap_fetchstruct($this->inStream,$msg_num); //echo gettype($struct); return $struct; } 函数 proc_struct($msg_part, $part_no, $msg_num) { if ($msg_part->ifdisposition) { //参见如果它有一个处置,我唯一知道的就是一个附件 //让我们检查一下 if ($msg_part->disposition == "attachment") { $att_name = "未知"; for ($lcv = 0; $lcv 参数); $lcv ) { $param = $msg_part->参数[$lcv ]; if ($param->attribute == "name") { $att_name = $param->value; break; } } $att_name = $this->decode_mime_string($att_name); $att_path = $this->用户名."\".$att_name; $this- >attach[$this->num_of_attach]=$att_name; //登记附件列表 $this->num_of_attach ; //登记附件数量 /* $att_path = $this->username."\".$this->decode_mime_string($att_name); if ($this->attach=="" ) $this->attach = $att_name; else $this->attach .= ";".$att_name; */ if (!is_dir($this- >用户名)) mkdir($this->用户名,0700); $fp=fopen($att_path,"w"); switch ($msg_part->encoding) { 情况 3: // base64 fputs($fp,imap_base64( imap_fetchbody($this->inStream,$msg_num,$part_no))); break; 情况 4: // QP fputs($fp,imap_qprint(imap_fetchbody($this->inStream,$) msg_num,$part_no))); break; 默认: fputs($fp,imap_fetchbody($this->inStream,$msg_num,$part_no)); break; } fclose($fp); //if ($msg_part->type=="5"){ // echo "
n"; // echo " n"; //} } // END IF ATTACHMENT else //NOT ifdisposition { // 我猜它除了附件之外还用于其他用途??? } } else { //不是附件,让我们看看这部分是什么... switch ($msg_part->type) { case 0: $mime_type = "text"; break; case 1: $mime_type = "multipart"; // 嘿,为什么不使用这个函数来处理所有的部分 //此多部分部分 $this->num_msg_parts = count($msg_part->parts); for ($i = 0; $i num_msg_parts; $i ) { if ($part_no != "") { $part_no = $part_no."."; } for ($i = 0; $i parts); $i ) { $this->proc_struct($msg_part->parts[$i], $part_no.($i 1), $msg_num); } } break; 情况 2: $mime_type = "message"; break; 情况 3: $mime_type = "application"; break; 情况 4: $mime_type = "audio"; break; 情况 5: $mime_type = "image"; break; 情况 6: $ mime_type = "video"; break; 情况 7: $mime_type = "model"; break; 默认值: $mime_type = "unknown"; // 嗯.... } $full_mime_type = $mime_type."/".$msg_part->subtype; $full_mime_type = strtolower($full_mime_type); // 决定如何处理这部分 // 如果你想显示它,请找出编码并回显 switch ($msg_part->encoding) { 情况 0: 情况 1: if ($this->num_msg_parts == 0){ echo ereg_replace("rn"," rn",imap_body ($this->inStream,$msg_num)); } else{ if ($part_no!=""){ echo ereg_replace("rn"," rn",imap_fetchbody($this->inStream,$msg_num,$part_no)); } } break; 情况 3: //BASE64 if ($full_mime_type=="text/plain"){ if ($this->num_msg_parts == 0){ $content=imap_base64(imap_body($this->inStream,$msg_num) )); } else{ $content = imap_base64(imap_fetchbody($this->inStream,$msg_num,$part_no)); $att_path = $this->用户名 。 "\ 文本内容.txt"; $fp = fopen($att_path,"w"); fputs($fp,$content); fclose($fp); $this ->attach[$this->num_of_attach]="文本内容.txt"; $this->num_of_attach ; } echo $content; } if ($full_mime_type=="text/html"){ $att_path = $this->用户名 . "\超文本内容.htm"; $fp = fopen($att_path,"w"); fputs($fp,imap_base64(imap_fetchbody($this->inStream,$msg_num,$part_no)) ); fclose($fp); $this->attach[$this->num_of_attach]="超文本内容.htm"; $this->num_of_attach ; } break; 情况4: //QPRINT //使用imap_qprint解码 if ($this->num_msg_parts == 0){ echo ereg_replace("n"," ",imap_qprint(imap_body($this->inStream,$msg_num))); } else{ echo ereg_replace("n"," ",imap_qprint(imap_fetchbody( $this->inStream,$msg_num,$part_no))); } if ($full_mime_type=="text/html"){ $att_path = $this->用户名 . "\qp超文本内容.htm"; $fp = fopen($att_path,"w"); fputs($fp,imap_base64(imap_fetchbody($this->inStream,$msg_num,$part_no) )); fclose($fp); $this->attach[$this->num_of_attach]="qp超文本内容.htm"; $this->num_of_attach ; } break; 情况 5: // 不确定这是否需要解码 echo ereg_replace("n"," ",imap_fetchbody($this->inStream,$msg_num )); break; 默认: //echo ereg_replace("n"," ",imap_fetchbody($this->inStream,$msg_num,$part_no)); Break; } } } }; ?> myimap 的扩展类,及读取一封邮件的例子(mail_read.php) require("myimap.php"); class myimap_ext extends myimap { function get_mail_subject( $msg_no){ $msgHeader = @imap_header($this->inStream, $msg_no); if (isset($msgHeader->subject)) $sub = trim($this->decode_mime_string ($msgHeader->subject)); if ($sub == "") $sub = "无主题"; return "Fw:".$sub; } function print_attaches(){ for ($i=0;$iattach);$i ){ echo "用户名."\".$this ->附加[$i]."">".$this->附加[$i]." "; } } function list_attaches(){ for ($i=0;$iattach);$i ){ if ($i==0 ) $attaches = $this->attach[$i]; else $attaches .= ";".$this->attach[$i]; } return $attaches; } } $imap=new myimap_ext; $imap->hostname="localhost"; $imap->port=143; $imap->username="name"; $imap->userpwd="password"; $imap->open(); $mail_struct=$imap-> get_struct($msg); $imap->proc_struct($mail_struct,"",$msg); if ($imap->num_of_attach > 0){ $imap->print_attaches(); } @$imap->close(); ?> myimap 的示例(mail_list.php) require("myimap .php"); $imap=new myimap; $imap->hostname="localhost"; $imap->port=143; $imap->username= "名称"; $imap->userpwd="密码"; $imap->open(); if ($page=="") $page=0; $imap->CheckMailBox(10,$page); @$imap->close(); ?> 如何发送附件(转) 我经常听到这样一个问题:“我有一个从网站发来的合同。我如何通过表单发送的电子邮件添加一个附件呢?” 首先我要说的是要做到这个没有什么简单的办法。你要很好的理解PHP或 其他的服务器端的脚本语言。当然你需要一个真正支持PHP的网站的账号。如果满足了这个前提,在你读完之后就可以用PHP发送带附件的电子邮件了。 1. 附件是如何工作的 如果你曾经在PHP的手册中搜索过“附件”函数,那么结果可能都没有(至少在我写论文的时间还没有)。很多时间来了解这方面的知识。 你也许会想当你给某人发送一封带附件的电子邮件时,附件是和邮件一起达到实用的信箱里的(比如,如果你给他/她发了一个PNG的图片文件,他/她的信箱里会包含一个txt文件(电子邮件)和一个.png文件(附件))。但这不是它的工作原理。当你加入一个附件时,你的邮件程序把附件转换成纯文本文件,并在你写的内容(实际的电子邮件)后面插入这个文本块。这个,当你把所有的东西发出来后,实例的信箱里只有一个纯文本文件--一个同时包含附件和实际电子邮件内容的文件。 下面是一个附件带(一个HTML文件)电子邮件的示例。我已经注意到其中重要的了几行: 返回路径: 日期:2000 年 5 月 22 日星期一 19:17:29 0000 发件人:某人 收件人:人 消息 ID: 内容类型:多部分/混合; border="396d983d6b89a" 主题:这是主题 --396d983d6b89a 内容类型:文本/纯文本; charset=iso-8859-1 内容传输编码:8位 这是电子邮件的正文。 --396d983d6b89a 内容类型:text/html; name=attachment.html 内容处置:内联; filename=attachment.html 内容传输编码:8位 附件 这是附加的 HTML 文件 --396d983d6b89a-- 前面的7行是邮件的头,其中注释的是内容类型头部分。这个头告诉邮件程序电子邮件是由一个以上的部分组成的。清晰附件的邮件只有一个部分:消息本身。 带附件的电子版通常至少由两部分组成:消息和附件。这样,带两个附件的邮件由三部分组成:消息,第一个附件和第二个附件。 带附件的电子邮件的不同部分之间用分界线来分隔。分界线在Content-type头中定义。邮件的每个新部分以两个连字号(--)和分界线开始。最后一个分界线后也有两个个连字号,表示这个邮件中没有其他的部分了。 在每个分界线后都有一些行,用于告诉邮件程序这个部分内容的类型。比如,看看上面例子中第一个分界线后面的两行--以Content-type: text/plain的行。这些行说明后面的部分是ISO-8859-1字符集的纯文本。跟在第二个分界线后面的行告诉邮件程序现在的部分是一个HTML文件,它的名字是“attachment.html”。 内容处置这持告诉邮件程序如果可能就在嵌入的方式显示附件。现在新的邮件程序会在消息后显示HTML的内容。如果Content-disposition被设为附件,那么邮件程序就不会显示HTML文件的内容,而是显示一个连接到文件的图标(或其他类似的东西)。收件一般情况下,如果附件是一些文本(包含HTML),内容配置会被设为内联,这是因为现在大多数邮件程序能够不借助其他浏览器而直接显示附件(文本)的内容。如果附件不是文本(比如图片或其它类似的内容),Content-disposition就设为attachment。 2. 用PHP生成带附件的电子邮件 这里一个例子,告诉你如果把一个定义好的HTML文件加为邮件的附件: # 我们首先写实际的消息内容 $emailBody = "This is text that goes into the body of the email."; # 然后我们要作为附件的HTML文件 $attachment = " The attached file This is the attached HTML file "; # 建立在邮件中分隔不同部分的分界线。 # 基本上,分界线可以是任意的字符串。 # 但是重要的一点是确定一个写邮件的人 # 这会随意写出的字符串,所以我们用 # uniqid函数来产生一个随机的字符串。 $boundary = uniqid( ""); # 现在我们要建立邮件头。不要忘了插入 # Content-type头来说明这个邮件包含一个或更多的附件。 $headers = "From: [email]someone@example.com[/email] Content-type: multipart/mixed; boundary="$boundary""; # 好,现在我们已经有了邮件的所有内容。 # 下一件事是修改邮件的主体。 $emailBody = "--$boundary Content-type: text/plain; charset=iso-8859-1 Content-transfer-encoding: 8bit $emailBody --$boundary Content-type: text/html; name=attachment.html Content-disposition: inline; filename=attachment.html Content-transfer-encoding: 8bit $attachment --$boundary--"; # 现在可以把邮件发出去了 mail( "[email]person@eksempel.dk[/email]", "The subject", $emailBody, $headers); ?> 3. 把用户上传的文件作为附件 你也许会觉得上面的例子难以理解,但下面...。在下面的例子中事情更难了,因为我们要用一个表单让用户上传他们的文件,并把这个文件作为我们要发的邮件的附件。麻烦的是我们不能预先知道文件的MIME类型。在前面的例子中,我们已经知道该它是一个HTML文件,所以给这个附件设置Content-type头是很简单的。在下面的例子中,MIME类型可能是任意的,因为用户可能会上传一个HTML文件,一个PNG文件,一个vCard文件,或者其它的东西。让我们来看看例子: # 现在我们来生成表单。在产生可以上传文件的表单时, # 不要忘了把
n"; # 如果用户已经按了"Send"按钮" if ($send) { # 定义分界线 $boundary = uniqid( ""); # 生成邮件头 $headers = "From: $from Content-type: multipart/mixed; boundary="$boundary""; # 确定上传文件的MIME类型 if ($attachment_type) $mimeType = $attachment_type; # 如果浏览器没有指定文件的MIME类型, # 我们可以把它设为"application/unknown". else $mimeType = "application/unknown"; # 确定文件的名字 $fileName = $attachment_name; # 打开文件 $fp = fopen($attachment, "r"); # 把整个文件读入一个变量 $read = fread($fp, filesize($attachment)); # 好,现在变量$read中保存的是包含整个文件内容的文本块。 # 现在我们要把这个文本块转换成邮件程序可以读懂的格式 # 我们用base64方法把它编码 $read = base64_encode($read); # 现在我们有一个用base64方法编码的长字符串。 # 下一件事是要把这个长字符串切成由每行76个字符组成的小块 $read = chunk_split($read); # 现在我们可以建立邮件的主体 $body = "--$boundary Content-type: text/plain; charset=iso-8859-1 Content-transfer-encoding: 8bit $body --$boundary Content-type: $mimeType; name=$fileName Content-disposition: attachment; filename=$fileName Content-transfer-encoding: base64 $read --$boundary--"; # 发送邮件 mail($to, $subject, $body, $headers); } ?> 这就是全部内容。如果你不能很好地理解上面的例子,我的建议是给你自己发送几个带附件的邮件,然后仔细研究邮件的源代码。