1、实现SMTP协议的类dsmtp.cls.php:
<?php
// 通过socket实现SMTP协议的功能 // version: 1.1 // author : DCC // create : 2014-01-17 23:38:24 // modify : 2014-01-18 16:59:04 // more : http://www.thinkful.cn/archives/389.html class Dmail_smtp{
var $socket;
var $host;
var $user;
var $pwd;
var $port;
var $nickname;
var $weburl;
// 初始化 function__construct($host, $user, $pwd, $port=
25, $webname=
' 大超超在思考 ', $weburl=
" www.thinkful.cn "){
$
this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$
this->host = $host;
$
this->user = $user;
$
this->pwd = $pwd;
$
this->port = $port;
$
this->nickname = $webname;
$
this->weburl = $weburl;
}
// 发邮件 function smtp($to, $
from, $subject, $body){
$conn = socket_connect($
this->socket, $
this->host, $
this->port);
if( $conn ){
// 接收连接成功的消息 $msg =
" succeed connect to ".$
this->host.
" : ".$
this->port.
" \n ";
$msg .= $
this->_r();
// 开始认证过程 $
this->_w(
" HELO ".$
this->weburl.
" \r\n ");
$msg .= $
this->_r();
$
this->_w(
" AUTH LOGIN ".base64_encode($
this->user).
" \r\n ");
$msg .= $
this->_r();
$
this->_w(base64_encode($
this->pwd).
" \r\n ");
$msg .= $
this->_r();
// 认证成功 if( stripos($msg,
' 235 Authentication successful ')!==FALSE ){
$
this->_w(
" MAIL FROM:<{$from}>\r\n ");
$msg .= $
this->_r();
$
this->_w(
" RCPT TO:<{$to}>\r\n ");
$msg .= $
this->_r();
$
this->_w(
" DATA\r\n ");
$msg .= $
this->_r();
// 发送头和正文 $data = $
this->_genHeader($to, $
from, $subject)
.
" \r\n ".$
this->_genBody($body);
$
this->_w($data);
$
this->_w(
" \r\n.\r\n ");
$msg .= $
this->_r();
$
this->_w(
" QUIT\r\n ");
$msg .= $
this->_r();
}
}
return $msg;
}
// 生成头部 private function _genHeader($to, $
from, $subject){
$header =
" MIME-Version:1.0\r\n ";
$header .=
" Content-Type: text/plain; charset=\"utf-8\"\r\n ";
$header .=
" Subject: =?utf-8?B? ".base64_encode($subject).
" ?=\r\n ";
$header .=
" From: ".$
this->nickname.
" < ".$
from.
" >\r\n ";
$header .=
" To: ".$to.
" \r\n ";
$header .=
" Date: ".date(
" r ").
" \r\n ";
list($msec, $sec) = explode(
" ", microtime());
$header .=
" Message-ID: <DCC_ ".date(
" YmdHis ").
" . ".($msec*
1000000).
" . ".$
from.
" >\r\n ";
return $header;
}
// 生成正文 private function _genBody($body){
$body = preg_replace(
" /(^|(\r\n))(\.)/ ",
" \1.\3 ", $body);
return $body;
}
// @发送控制流 // var: 控制代码 private function _w($s){
socket_write($
this->socket, $s);
}
// @读取返回的数据 private function _r(){
return socket_read($
this->socket,
1024);
}
}
2、实现POP3协议的类dpop3.cls.php:
<?php
// 通过socket实现pop3协议的功能 // version: 1.2 // author : DCC // create : 2014-01-18 11:26:53 // modify : 2014-01-18 22:57:26 // more : http://www.thinkful.cn/archives/389.html class Dmail_pop3{
var $socket;
var $host;
var $user;
var $pwd;
var $port;
var $content;
// 初始化 function __construct($host, $user, $pwd, $port=
110){
$
this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$
this->host = $host;
$
this->user = $user;
$
this->pwd = $pwd;
$
this->port = $port;
}
// 收邮件 function pop3(){
$conn = socket_connect($
this->socket, $
this->host, $
this->port);
if( $conn ){
// 接收连接成功的消息 $msg =
" DCC: succeed connect to ".$
this->host.
" : ".$
this->port.
" \n ";
$msg .= $
this->_r();
// 开始认证过程 $
this->_w(
" USER ".$
this->user.
" \r\n ");
$msg .= $
this->_r();
$
this->_w(
" PASS ".$
this->pwd.
" \r\n ");
$msg .= $
this->_r();
// 认证成功 if( substr_count($msg,
' +OK ')>=
3 ){
// 向服务器发送请求邮箱信息 $
this->_w(
" STAT\r\n ");
$mail_info = $
this->_r();
$msg .= $mail_info;
preg_match(
' /\+OK\s(\d+)\s(\d+)/ ', $mail_info, $m);
$mail_num = $m[
1];
$mail_len = $m[
2];
// 向服务器发送邮件i信息的请求 $
this->content =
'';
for( $i=
1; $i<=$mail_num; $i++ ){
// 查看该邮件的信息 $
this->_w(
" LIST {$i}\r\n ");
usleep(
160000);
// waiting 0.16s $mail_info = $
this->_r();
$msg .= $mail_info;
preg_match(
' /\+OK\s(\d+)\s(\d+)/ ', $mail_info, $m);
// 接收服务器返回的信息 $
this->_w(
" RETR {$i}\r\n ");
$msg.=
' DCC: reading mail(id= '.$m[
1].
' )\'s content(length= '.$m[
2].
' byte): '.
" \n ";
$data =
'';
while( strlen($data)<$m[
2] ){
$msg .=
' . ';
$data .= socket_read($
this->socket,
4096);
}
$
this->content .= $data;
$msg.=
" \nDCC: mail(id= ".$m[
1].
' )\'s content(length= '.$m[
2].
' byte) read complete. '.
" \n ";
}
}
}
return $msg;
}
// 返回收取邮件内容 function getContent(){
return $
this->content;
}
// @发送控制流 // var: 控制代码 private function _w($s){
socket_write($
this->socket, $s);
}
// @读取返回的数据 // var: 数据长度 private function _r($len=
1024){
return socket_read($
this->socket, $len);
}
}
// 调用SMTP时 require_once
' dsmtp.cls.php ';
$host =
" smtp.qq.com ";
// 使用QQ邮箱和密码 $user =
' *******@qq.com ';
$pwd =
' ******* ';
$dmail =
new Dmail_smtp($host, $user, $pwd);
$msg = $dmail->smtp($to, $
from, $subject, $body);
// ******************************** // ******************************** // 调用POP3时(后续处理复杂一点) require_once
' dpop3.cls.php ';
$host =
" pop.qq.com ";
$dmail =
new Dmail_pop3($host, $user, $pwd);
$msg = $dmail->pop3();
$ret = $msg;
if( strpos($msg,
' read complete ')!==FALSE ){
$ct = $dmail->getContent();
$mail_list_arr = explode(
' X-QQ-SSF: ', $ct);
array_shift($mail_list_arr);
// 去除第一个 $mail_list_arr = array_reverse($mail_list_arr);
foreach( $mail_list_arr
as $v ){
// 中文标题的处理 if( preg_match(
' /Subject: =\?([^?]+)\?B\?([^?]+)\?=/i ', $v, $subject) ){
$tmp_s = base64_decode($subject[
2]);
$tmp_s = $subject[
1]==
' gbk '||$subject[
1]==
' gb2312 '? iconv(
' gbk ',
' utf-8 ', $tmp_s) : $tmp_s;
}
// 英文标题 else if( preg_match(
' /Subject: (.*?)\r\n/i ', $v, $subject) ){
$tmp_s = $subject[
1];
}
else{
$tmp_s =
' 邮件标题 ';
}
preg_match(
' /From: [^<]+<(.*?)>/i ', $v, $
from);
preg_match(
' /Date: (.*?)\r\n/i ', $v, $date);
$mail_list .= $tmp_s.
' |#DCC_LIST_INNER#| ' .$
from[
1].
' |#DCC_LIST_INNER#| ' .$date[
1].
' |#DCC_MAIL_LIST_SEP#| ';
}
$ret .=
' |#DCC_POP3_DATA_SEP#| '.$mail_list;
}
echo $ret;
die();