首页 > 开发 > PHP > 正文

使用PHP的Socket写的POP3类

2024-05-04 22:59:05
字体:
来源:转载
供稿:网友

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

<?php
/**
 * 类名:socketpopclient
 * 功能:pop3 协议客户端的基本操作类
 * 作者:heiyeluren <http://blog.csdn.net/heiyeshuwu>
 * 时间: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     <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('[email protected]', '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();
*/
?> 

 

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表