使用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数组总结篇(一)
Sep 30 PHP
phpmyadmin导入(import)文件限制的解决办法
Dec 11 PHP
推荐几个开源的微信开发项目
Dec 28 PHP
PHP中大于2038年时间戳的问题处理方案
Mar 03 PHP
MacOS 安装 PHP的图片裁剪扩展Tclip
Mar 25 PHP
基于PHP实现数据分页显示功能
May 26 PHP
php倒计时出现-0情况的解决方法
Jul 28 PHP
PHP入门教程之自定义函数用法详解(创建,调用,变量,参数,返回值等)
Sep 11 PHP
php实现有序数组打印或排序的方法【附Python、C及Go语言实现代码】
Nov 10 PHP
laravel配置Redis多个库的实现方法
Apr 10 PHP
php常用的工具开发整理
Sep 26 PHP
使用 PHP Masked Package 屏蔽敏感数据的实现方法
Oct 15 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
香妃
2021/03/03 冲泡冲煮
Apache环境下PHP利用HTTP缓存协议原理解析及应用分析
2010/02/16 PHP
php表单提交问题的解决方法
2011/04/12 PHP
Zend Framework教程之模型Model用法简单实例
2016/03/04 PHP
PHP生成短网址方法汇总
2016/07/12 PHP
ecshop添加菜单及权限分配问题
2017/11/21 PHP
JScript中的undefined和&quot;undefined&quot;的区别
2007/03/08 Javascript
jquery 分页控件实现代码
2009/11/30 Javascript
js jquery验证银行卡号信息正则学习
2013/01/21 Javascript
初步认识JavaScript函数库jQuery
2015/06/18 Javascript
倾力总结40条常见的移动端Web页面问题解决方案
2016/05/24 Javascript
Angular JS 生成动态二维码的方法
2017/02/23 Javascript
基于JavaScript表单脚本(详解)
2017/10/18 Javascript
Node.js使用Angular简单示例
2018/05/11 Javascript
JS实现的3des+base64加密解密算法完整示例
2018/05/18 Javascript
如何解决vue2.0下IE浏览器白屏问题
2018/09/13 Javascript
[05:36]DOTA2 2015国际邀请赛中国区预选赛第四日TOP10
2015/05/29 DOTA
解析Python中的变量、引用、拷贝和作用域的问题
2015/04/07 Python
pandas DataFrame数据转为list的方法
2018/04/11 Python
机器学习之KNN算法原理及Python实现方法详解
2018/07/09 Python
DRF跨域后端解决之django-cors-headers的使用
2019/01/27 Python
python保存字典和读取字典的实例代码
2019/07/07 Python
Pytorch 实现sobel算子的卷积操作详解
2020/01/10 Python
python语言中有算法吗
2020/06/16 Python
套娃式文件夹如何通过Python批量处理
2020/08/23 Python
纯CSS3实现的井字棋游戏
2020/11/25 HTML / CSS
美的官方商城:Midea
2016/09/14 全球购物
地球鞋加拿大官网:Earth Shoes Canada
2020/11/17 全球购物
无故旷工检讨书
2014/01/26 职场文书
安全教育演讲稿
2014/05/09 职场文书
排查整治工作方案
2014/06/09 职场文书
节能环保口号
2014/06/12 职场文书
个人合伙协议书范本
2014/10/14 职场文书
2014年学生工作总结
2014/11/20 职场文书
《将心比心》教学反思
2016/02/23 职场文书
心得体会该怎么写呢?
2019/06/27 职场文书