博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PHP+socket+SMTP、POP3协议发送、接收邮件
阅读量:7043 次
发布时间:2019-06-28

本文共 5817 字,大约阅读时间需要 19 分钟。

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);
    }
}
3、界面——代码就不贴出来了,看基本调用方法:
//
 调用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();

转载于:https://www.cnblogs.com/qhorse/p/4594683.html

你可能感兴趣的文章
写一个简单的运行Django项目的脚本
查看>>
Django
查看>>
解决 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YE
查看>>
iOS开发如何实现消息推送机制
查看>>
Android xml application属性详解
查看>>
Android Push Notification实现信息推送使用
查看>>
elk6.4(rpm)安装及kibana汉化
查看>>
发表图片, 弹出界面, 类似QQ发说说时候添加照片的界面(不太会说,见谅)
查看>>
js语句执行顺序
查看>>
Android短信开发相关信息记录
查看>>
jdk堆、栈的分析工具--jmap、jstack
查看>>
target和currentTarget的区别
查看>>
RSpec控制器测试重构
查看>>
split,tr,cut,tac
查看>>
Activity的四种加载方式
查看>>
Babel的register特性使用
查看>>
Vim的分屏功能
查看>>
linux各种版本静态IP设置
查看>>
Android改包1
查看>>
spring 配置线程池
查看>>