Go homepage(回首页)
Upload pictures (上传图片)
Write articles (发文字帖)

The author:(作者)归海一刀
published in(发表于) 2014/2/10 6:51:51
使用PHP的Socket写的POP3类_[PHP教程]

使用PHP的Socket写的POP3类_[PHP教程]

查看 POP3/SMTP 协议的时候想尝试一下自己写一个操作类,核心没啥,就是使用 fsockopen ,然后写入/接收数据,只实现了最核心的部分功能,当作是学习 Socket 操作的练手。其中参考了 RFC 2449和一个国外的简单Web邮件系统 Uebimiau 的部分代码,不过绝对没有抄他滴,HOHO,绝对原创。如果你喜欢,请收藏,随便修改,嗯,但是记得不要删除偶类里的声名,毕竟偶也是辛辛苦苦写了好几天呐。
另外,欢迎自由发挥,改善或者修正这个类,希望能够为你所用。代码没有认真仔细的调试,发现bug请自己修正,HOHO!


/**
* 类名:SocketPOPClient
* 功能:POP3 协议客户端的基本操作类
* 作者:heiyeluren
* 时间:2006-7-3
* 参考:RFC 2449, Uebimiau
* 授权:BSD License
*/


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
\n";
echo "[Error Num] : intErrorNum
\n";
exit;
}


//输出主机信息
function printHost()
{
echo "[Host] : this->strHost
\n";
echo "[Port] : this->intPort
\n";
echo "[Email] : this->strEmail
\n";
echo "[Passwd] : ********
\n";
exit;
}


//输出连接信息
function printConnect()
{
echo "[Connect] : this->resHandler
\n";
echo "[Request] : this->strRequest
\n";
echo "[Response] : this->strResponse
\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();
*/
?>


来源:CSDN






If you have any requirements, please contact webmaster。(如果有什么要求,请联系站长)





QQ:154298438
QQ:417480759