搜索
首页php教程php手册用PHP的Socket写的POP3类

【摘 要】 查看 POP3/SMTP 协议的时候想尝试一下自己写一个操作类,核心没啥,就是使用 fsockopen ,然后写入/接收数据,只实现了最核心的部分功能,当作是学习 Socket 操作的练手。
查看 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)            {
                $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)            {
                $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();
*/
?>



声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境