使用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 相关文章推荐
屏蔽机器人从你的网站搜取email地址的php代码
Nov 14 PHP
thinkphp中连接oracle时封装方法无法用的解决办法
Jun 17 PHP
解决PHP mysql_query执行超时(Fatal error: Maximum execution time …)
Jul 03 PHP
浅析php fwrite写入txt文件的时候用 \r\n不能换行的问题
Aug 06 PHP
微信公众平台消息接口校验与消息接口响应实例
Dec 23 PHP
php实现将Session写入数据库
Jul 26 PHP
使用PHPCMS搭建wap手机网站
Sep 20 PHP
编写PHP脚本来实现WordPress中评论分页的功能
Dec 10 PHP
Laravel框架实现发送短信验证功能代码
Jun 06 PHP
PHP实现的多维数组去重操作示例
Jul 21 PHP
PHP使用标准库spl实现的观察者模式示例
Aug 04 PHP
在laravel-admin中列表中禁止某行编辑、删除的方法
Oct 03 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
php日期操作技巧小结
2016/06/25 PHP
基于php流程控制语句和循环控制语句(讲解)
2017/10/23 PHP
Laravel中unique和exists验证规则的优化详解
2018/01/28 PHP
全面了解addEventListener和on的区别
2016/07/14 Javascript
Three.js快速入门教程
2016/09/09 Javascript
网络传输协议(http协议)
2016/11/18 Javascript
微信小程序自定义导航隐藏和显示功能
2017/06/13 Javascript
nodejs 子进程正确的打开方式
2017/07/03 NodeJs
vue单页面应用打开新窗口显示跳转页面的实例
2018/09/21 Javascript
微信小程序实现二维码签到考勤系统
2020/01/16 Javascript
使用PreloadJS加载图片资源的基础方法详解
2020/02/03 Javascript
python3 面向对象__类的内置属性与方法的实例代码
2018/11/09 Python
Python实现的在特定目录下导入模块功能分析
2019/02/11 Python
python3使用matplotlib绘制条形图
2020/03/25 Python
eclipse创建python项目步骤详解
2019/05/10 Python
Python 获取windows桌面路径的5种方法小结
2019/07/15 Python
Python实现微信翻译机器人的方法
2019/08/13 Python
Python Subprocess模块原理及实例
2019/08/26 Python
Django之使用celery和NGINX生成静态页面实现性能优化
2019/10/08 Python
python 解决flask 图片在线浏览或者直接下载的问题
2020/01/09 Python
PyTorch实现AlexNet示例
2020/01/14 Python
python实现百度OCR图片识别过程解析
2020/01/17 Python
浅析Python中字符串的intern机制
2020/10/03 Python
python 匿名函数与三元运算学习笔记
2020/10/23 Python
python time.strptime格式化实例详解
2021/02/03 Python
CSS Grid布局教程之浏览器开启CSS Grid Layout汇总
2014/12/30 HTML / CSS
长曲棍球装备:Lacrosse Monkey
2020/12/02 全球购物
2013的个人自我评价
2013/12/26 职场文书
中国好声音华少广告词
2014/03/17 职场文书
法律系毕业生自荐信范文
2014/03/27 职场文书
辞职信格式范文
2015/05/13 职场文书
《小乌鸦爱妈妈》教学反思
2016/02/19 职场文书
2016优秀班主任个人先进事迹材料
2016/02/26 职场文书
导游词之镇江焦山
2019/11/21 职场文书
MongoDB安装使用并实现Python操作数据库
2021/06/28 MongoDB
一篇文章带你掌握SQLite3基本用法
2022/06/14 数据库