使用PHP Socket写的POP3类


Posted in PHP onOctober 30, 2013

查看 POP3/SMTP 协议的时候想尝试一下自己写一个操作类,核心没啥,就是使用 fsockopen ,然后写入/接收数据,只实现了最核心的部分功能,当作是学习 Socket 操作的练手。其中参考了 RFC 2449和一个国外的简单Web邮件系统 Uebimiau 的部分代码,不过绝对没有抄他滴,HOHO,绝对原创。

<?php 
class SocketPOPClient 
{ 
    var $strMessage        = ''; 
    var $intErrorNum    = 0; 
    var $bolDebug        = false;     var $strEmail        = ''; 
    var $strPasswd        = ''; 
    var $strHost        = ''; 
    var $intPort        = 110; 
    var $intConnSecond    = 30; 
    var $intBuffSize    = 8192;

    var $resHandler        = NULL; 
    var $bolIsLogin        = false; 
    var $strRequest        = ''; 
    var $strResponse    = ''; 
    var $arrRequest        = array(); 
    var $arrResponse    = array();

    //--------------- 
    // 基础操作 
    //---------------
    //构造函数 
    function SocketPOP3Client($strLoginEmail, $strLoginPasswd, $strPopHost='', $intPort='') 
    { 
        $this->strEmail        = trim(strtolower($strLoginEmail)); 
        $this->strPasswd    = trim($strLoginPasswd); 
        $this->strHost        = trim(strtolower($strPopHost));
        if ($this->strEmail=='' || $this->strPasswd=='') 
        { 
            $this->setMessage('Email address or Passwd is empty', 1001); 
            return false; 
        } 
        if (!PReg_match("/^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/i", $this->strEmail)) 
        { 
            $this->setMessage('Email address invalid', 1002); 
            return false; 
        } 
        if ($this->strHost=='') 
        { 
            $this->strHost = substr(strrchr($this->strEmail, "@"), 1); 
        } 
        if ($intPort!='') 
        { 
            $this->intPort = $intPort; 
        } 
        $this->connectHost(); 
    } 
    //连接服务器 
    function connectHost() 
    { 
        if ($this->bolDebug) 
        { 
            echo "Connection ".$this->strHost." ...\r\n"; 
        } 
        if (!$this->getIsConnect()) 
        { 
            if ($this->strHost=='' || $this->intPort=='') 
            { 
                $this->setMessage('POP3 host or Port is empty', 1003); 
                return false;             
            } 
            $this->resHandler = @fsockopen($this->strHost, $this->intPort, &$this->intErrorNum, &$this->strMessage, $this->intConnSecond); 
            if (!$this->resHandler) 
            { 
                $strErrMsg = 'Connection POP3 host: '.$this->strHost.' failed'; 
                $intErrNum = 2001; 
                $this->setMessage($strErrMsg, $intErrNum); 
                return false; 
            } 
            $this->getLineResponse(); 
            if (!$this->getRestIsSucceed()) 
            { 
                return false; 
            } 
        } 
        return true; 
    }
    //关闭连接 
    function closeHost() 
    { 
        if ($this->resHandler) 
        { 
            fclose($this->resHandler); 
        } 
        return true; 
    }
    //发送指令 
    function sendCommand($strCommand) 
    { 
        if ($this->bolDebug) 
        { 
            if (!preg_match("/PASS/", $strCommand)) 
            { 
                echo "Send Command: ".$strCommand."\r\n"; 
            } 
            else 
            { 
                echo "Send Command: PASS ******\r\n"; 
            }
        } 
        if (!$this->getIsConnect()) 
        { 
            return false; 
        } 
        if (trim($strCommand)=='') 
        { 
            $this->setMessage('Request command is empty', 1004); 
            return false; 
        } 
        $this->strRequest = $strCommand."\r\n"; 
        $this->arrRequest[] = $strCommand; 
        fputs($this->resHandler, $this->strRequest); 
        return true; 
    }
    //提取响应信息第一行 
    function getLineResponse() 
    { 
        if (!$this->getIsConnect()) 
        { 
            return false; 
        } 
        $this->strResponse = fgets($this->resHandler, $this->intBuffSize); 
        $this->arrResponse[] = $this->strResponse;
        return $this->strResponse;         
    }
    //提取若干响应信息,$intReturnType是返回值类型, 1为字符串, 2为数组 
    function getRespMessage($intReturnType) 
    { 
        if (!$this->getIsConnect()) 
        { 
            return false; 
        } 
        if ($intReturnType == 1) 
        { 
            $strAllResponse = ''; 
            while(!feof($this->resHandler)) 
            { 
                $strLineResponse = $this->getLineResponse(); 
                if (preg_match("/^\+OK/", $strLineResponse)) 
                { 
                    continue; 
                } 
                if (trim($strLineResponse)=='.') 
                { 
                    break; 
                } 
                $strAllResponse .= $strLineResponse; 
            } 
            return $strAllResponse; 
        } 
        else 
        { 
            $arrAllResponse = array(); 
            while(!feof($this->resHandler)) 
            { 
                $strLineResponse = $this->getLineResponse(); 
                if (preg_match("/^\+OK/", $strLineResponse)) 
                { 
                    continue; 
                } 
                if (trim($strLineResponse)=='.') 
                { 
                    break; 
                } 
                $arrAllResponse[] = $strLineResponse; 
            } 
            return $arrAllResponse;             
        } 
    }
    //提取请求是否成功 
    function getRestIsSucceed($strRespMessage='') 
    { 
        if (trim($responseMessage)=='') 
        { 
            if ($this->strResponse=='') 
            { 
                $this->getLineResponse(); 
            } 
            $strRespMessage = $this->strResponse; 
        } 
        if (trim($strRespMessage)=='') 
        { 
            $this->setMessage('Response message is empty', 2003); 
            return false; 
        } 
        if (!preg_match("/^\+OK/", $strRespMessage)) 
        { 
            $this->setMessage($strRespMessage, 2000); 
            return false; 
        } 
        return true; 
    }
    //获取是否已连接 
    function getIsConnect() 
    { 
        if (!$this->resHandler) 
        { 
            $this->setMessage("Nonexistent availability connection handler", 2002); 
            return false; 
        } 
        return true; 
    }

    //设置消息 
    function setMessage($strMessage, $intErrorNum) 
    { 
        if (trim($strMessage)=='' || $intErrorNum=='') 
        { 
            return false; 
        } 
        $this->strMessage    = $strMessage; 
        $this->intErrorNum    = $intErrorNum; 
        return true; 
    }
    //获取消息 
    function getMessage() 
    { 
        return $this->strMessage; 
    }
    //获取错误号 
    function getErrorNum() 
    { 
        return $this->intErrorNum; 
    }
    //获取请求信息 
    function getRequest() 
    { 
        return $this->strRequest;         
    }
    //获取响应信息 
    function getResponse() 
    { 
        return $this->strResponse; 
    }

    //--------------- 
    // 邮件原子操作 
    //---------------
    //登录邮箱 
    function popLogin() 
    { 
        if (!$this->getIsConnect()) 
        { 
            return false; 
        } 
        $this->sendCommand("USER ".$this->strEmail); 
        $this->getLineResponse(); 
        $bolUserRight = $this->getRestIsSucceed();
        $this->sendCommand("PASS ".$this->strPasswd); 
        $this->getLineResponse(); 
        $bolPassRight = $this->getRestIsSucceed();
        if (!$bolUserRight || !$bolPassRight) 
        { 
            $this->setMessage($this->strResponse, 2004); 
            return false; 
        }         
        $this->bolIsLogin = true; 
        return true; 
    }
    //退出登录 
    function popLogout() 
    { 
        if (!$this->getIsConnect() && $this->bolIsLogin) 
        { 
            return false; 
        } 
        $this->sendCommand("QUIT"); 
        $this->getLineResponse(); 
        if (!$this->getRestIsSucceed()) 
        { 
            return false; 
        } 
        return true; 
    }
    //获取是否在线 
    function getIsOnline() 
    { 
        if (!$this->getIsConnect() && $this->bolIsLogin) 
        { 
            return false; 
        } 
        $this->sendCommand("NOOP"); 
        $this->getLineResponse(); 
        if (!$this->getRestIsSucceed()) 
        { 
            return false; 
        } 
        return true;         
    }
    //获取邮件数量和字节数(返回数组) 
    function getMailSum($intReturnType=2) 
    { 
        if (!$this->getIsConnect() && $this->bolIsLogin) 
        { 
            return false; 
        } 
        $this->sendCommand("STAT"); 
        $strLineResponse = $this->getLineResponse(); 
        if (!$this->getRestIsSucceed()) 
        { 
            return false; 
        } 
        if ($intReturnType==1) 
        { 
            return     $this->strResponse; 
        } 
        else 
        { 
            $arrResponse = explode(" ", $this->strResponse); 
            if (!is_array($arrResponse) || count($arrResponse)<=0) 
            { 
                $this->setMessage('STAT command response message is error', 2006); 
                return false; 
            } 
            return array($arrResponse[1], $arrResponse[2]); 
        } 
    }
    //获取指定邮件得session Id 
    function getMailSessId($intMailId, $intReturnType=2) 
    { 
        if (!$this->getIsConnect() && $this->bolIsLogin) 
        { 
            return false; 
        } 
        if (!$intMailId = intval($intMailId)) 
        { 
            $this->setMessage('Mail message id invalid', 1005); 
            return false; 
        } 
        $this->sendCommand("UIDL ". $intMailId); 
        $this->getLineResponse(); 
        if (!$this->getRestIsSucceed()) 
        { 
            return false; 
        } 
        if ($intReturnType == 1) 
        { 
            return     $this->strResponse; 
        } 
        else 
        { 
            $arrResponse = explode(" ", $this->strResponse); 
            if (!is_array($arrResponse) || count($arrResponse)<=0) 
            { 
                $this->setMessage('UIDL command response message is error', 2006); 
                return false; 
            } 
            return array($arrResponse[1], $arrResponse[2]); 
        } 
    }
    //取得某个邮件的大小 
    function getMailSize($intMailId, $intReturnType=2) 
    { 
        if (!$this->getIsConnect() && $this->bolIsLogin) 
        { 
            return false; 
        } 
        $this->sendCommand("LIST ".$intMailId); 
        $this->getLineResponse(); 
        if (!$this->getRestIsSucceed()) 
        { 
            return false; 
        } 
        if ($intReturnType == 1) 
        { 
            return $this->strResponse; 
        } 
        else 
        { 
            $arrMessage = explode(' ', $this->strResponse); 
            return array($arrMessage[1], $arrMessage[2]); 
        } 
    }
    //获取邮件基本列表数组 
    function getMailBaseList($intReturnType=2) 
    { 
        if (!$this->getIsConnect() && $this->bolIsLogin) 
        { 
            return false; 
        } 
        $this->sendCommand("LIST"); 
        $this->getLineResponse(); 
        if (!$this->getRestIsSucceed()) 
        { 
            return false; 
        } 
        return $this->getRespMessage($intReturnType); 
    }
    //获取指定邮件所有信息,intReturnType是返回值类型,1是字符串,2是数组 
    function getMailMessage($intMailId, $intReturnType=1) 
    { 
        if (!$this->getIsConnect() && $this->bolIsLogin) 
        { 
            return false; 
        } 
        if (!$intMailId = intval($intMailId)) 
        { 
            $this->setMessage('Mail message id invalid', 1005); 
            return false; 
        } 
        $this->sendCommand("RETR ". $intMailId); 
        $this->getLineResponse(); 
        if (!$this->getRestIsSucceed()) 
        { 
            return false; 
        } 
        return $this->getRespMessage($intReturnType); 
    }
    //获取某邮件前指定行, $intReturnType 返回值类型,1是字符串,2是数组 
    function getMailTopMessage($intMailId, $intTopLines=10, $intReturnType=1) 
    { 
        if (!$this->getIsConnect() && $this->bolIsLogin) 
        { 
            return false; 
        } 
        if (!$intMailId=intval($intMailId) || !$intTopLines=int($intTopLines)) 
        { 
            $this->setMessage('Mail message id or Top lines number invalid', 1005); 
            return false; 
        } 
        $this->sendCommand("TOP ". $intMailId ." ". $intTopLines); 
        $this->getLineResponse(); 
        if (!$this->getRestIsSucceed()) 
        { 
            return false; 
        } 
        return $this->getRespMessage($intReturnType); 
    }
    //删除邮件 
    function delMail($intMailId) 
    { 
        if (!$this->getIsConnect() && $this->bolIsLogin) 
        { 
            return false; 
        } 
        if (!$intMailId=intval($intMailId)) 
        { 
            $this->setMessage('Mail message id invalid', 1005); 
            return false; 
        } 
        $this->sendCommand("DELE ".$intMailId); 
        $this->getLineResponse(); 
        if (!$this->getRestIsSucceed()) 
        { 
            return false; 
        } 
        return true; 
    }
    //重置被删除得邮件标记为未删除 
    function resetDeleMail() 
    { 
        if (!$this->getIsConnect() && $this->bolIsLogin) 
        { 
            return false; 
        } 
        $this->sendCommand("RSET"); 
        $this->getLineResponse(); 
        if (!$this->getRestIsSucceed()) 
        { 
            return false; 
        } 
        return true;         
    }
    //--------------- 
    // 调试操作 
    //---------------
    //输出对象信息 
    function printObject() 
    { 
        print_r($this); 
        exit; 
    }
    //输出错误信息 
    function printError() 
    { 
        echo "[Error Msg] : $strMessage     <br>\n"; 
        echo "[Error Num] : $intErrorNum <br>\n"; 
        exit; 
    }
    //输出主机信息 
    function printHost() 
    { 
        echo "[Host]  : $this->strHost <br>\n"; 
        echo "[Port]  : $this->intPort <br>\n"; 
        echo "[Email] : $this->strEmail <br>\n"; 
        echo "[Passwd] : ******** <br>\n"; 
        exit; 
    }
    //输出连接信息 
    function printConnect() 
    { 
        echo "[Connect] : $this->resHandler <br>\n"; 
        echo "[Request] : $this->strRequest <br>\n"; 
        echo "[Response] : $this->strResponse <br>\n"; 
        exit; 
    } 
}
?>
<? 
//测试代码 
//例如:$o = SocketPOP3Client('邮箱地址', '密码', 'POP3服务器', 'POP3端口')
/* 
set_time_limit(0); 
$o = new SocketPOPClient('abc@126.com', '123456', 'pop.126.com', '110'); 
$o->popLogin(); 
print_r($o->getMailBaseList()); 
print_r($o->getMailSum(1)); 
print_r($o->getMailTopMessage(2, 2, 2)); 
$o->popLogout(); 
$o->closeHost(); 
$o->printObject(); 
*/ 
?>
PHP 相关文章推荐
php discuz 主题表和回帖表的设计
Mar 13 PHP
PHP无限分类(树形类)的深入分析
Jun 02 PHP
ThinkPHP3.1新特性之命名范围的使用
Jun 19 PHP
php通过array_merge()函数合并两个数组的方法
Mar 18 PHP
php输出全球各个时区列表的方法
Mar 31 PHP
Laravel 5 框架入门(三)
Apr 09 PHP
WampServer搭建php环境时遇到的问题汇总
Jul 23 PHP
基于thinkPHP框架实现留言板的方法
Oct 17 PHP
利用PHP判断是否是连乘数字串的方法示例
Jul 03 PHP
python进程与线程小结实例分析
Nov 11 PHP
Laravel5.1 框架Request请求操作常见用法实例分析
Jan 04 PHP
浅谈PHP中的那些魔术常量
Dec 02 PHP
腾讯QQ微博API接口获取微博内容
Oct 30 #PHP
FireFox浏览器使用Javascript上传大文件
Oct 30 #PHP
php使用ICQ网关发送手机短信
Oct 30 #PHP
PHP分页详细讲解(有实例)
Oct 30 #PHP
php预定义变量使用帮助(带实例)
Oct 30 #PHP
调整PHP的性能
Oct 30 #PHP
PHP数据过滤的方法
Oct 30 #PHP
You might like
function.inc.php超越php
2006/12/09 PHP
php封装的图片(缩略图)处理类完整实例
2016/10/19 PHP
重定向实现代码
2006/11/20 Javascript
JS实现仿新浪黄色经典滑动门效果代码
2015/09/27 Javascript
JavaScript常用数组算法小结
2016/02/13 Javascript
Bootstarp风格的toggle效果分享
2016/02/23 Javascript
jquery自动补齐功能插件flexselect用法示例
2016/08/06 Javascript
详解js中call与apply关键字的作用
2016/11/21 Javascript
基于JavaScript实现拖动滑块效果
2017/02/16 Javascript
jquery实现手机端单店铺购物车结算删除功能
2017/02/22 Javascript
Angular 5.0 来了! 有这些大变化
2017/11/15 Javascript
详解使用jest对vue项目进行单元测试
2018/09/07 Javascript
JS使用百度地图API自动获取地址和经纬度操作示例
2019/04/16 Javascript
微信小程序new Date()方法失效问题解决方法
2019/07/29 Javascript
react 原生实现头像滚动播放的示例
2020/04/21 Javascript
Postman内建变量常用方法实例解析
2020/07/28 Javascript
vue 使用post/get 下载导出文件操作
2020/08/07 Javascript
vue $router和$route的区别详解
2020/12/02 Vue.js
python实现查找excel里某一列重复数据并且剔除后打印的方法
2015/05/26 Python
python多线程方式执行多个bat代码
2016/06/07 Python
详解python的sorted函数对字典按key排序和按value排序
2018/08/10 Python
Python2和Python3的共存和切换使用
2019/04/12 Python
你还在@微信官方?聊聊Python生成你想要的微信头像
2019/09/25 Python
Python3打包exe代码2种方法实例解析
2020/02/17 Python
什么是python的必选参数
2020/06/21 Python
如何在网站上添加谷歌定位信息
2016/04/16 HTML / CSS
波兰最大的电商平台:Allegro.pl
2021/02/06 全球购物
会计系毕业个人自荐信格式
2013/09/23 职场文书
职专应届生求职信
2013/11/16 职场文书
期末自我鉴定
2014/01/23 职场文书
大学生村官座谈会发言材料
2014/05/25 职场文书
2014年环境卫生工作总结
2014/11/24 职场文书
巾帼标兵事迹材料
2014/12/26 职场文书
公证处委托书
2015/01/28 职场文书
师范生小学见习总结
2015/06/23 职场文书
2016应届毕业生就业指导课心得体会
2016/01/15 职场文书