使用PHP Socket写的POP3类
查看 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();
*/
?>