[PHP] PHP调用IMAP协议读取邮件类库

前端之家收集整理的这篇文章主要介绍了[PHP] PHP调用IMAP协议读取邮件类库前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

socket.PHP 为连接socket的类库

imap.PHP 基于socket的imap协议封装

test.PHP 进行测试

require_once 'socket.PHP';
require_once 'imap.PHP';
$imap=new Sina_Mail_Net_Imap("imap.sina.net:143",30,30);
$imap->capability();
$imap->id(array(
    'name'          => 'SinaMail OtherMail Client','version'       => '1','os'            => 'SinaMail OtherMail','os-version'    => '1.0',
));
$imap->login("xxxx@xxxxx","xxxx"$folders=$imap->getList('','*');
var_dump($folders$status = $imap->select('SENT'$status$ls = $imap->fetch(array(),1)">array('uid','internaldate','rfc822.size'));




foreach($ls as $k=>$i){
    $info=array($k),1)">array('rfc822'));
}

 

imap.PHP

<?PHP
class Sina_Mail_Net_Imap {
    const MAX_READ_SIZE = 100000000;
    const PATTERN_REQUEST_STRING_SEQUENCE   = '/{\d+}/'const PATTERN_RESPONSE_STRING_SEQUENCE  = '/{(\d+)}$/'const SEQUENCE_PARAM_NAME   = '[]'const PARTIAL_PARAM_NAME    = '<>'const PARAM_NO          = 1const PARAM_SINGLE      = 2const PARAM_PAIR        = 4const PARAM_LIST        = 8const PARAM_STRING      = 16const PARAM_NUMBER      = 32const PARAM_DATE        = 64const PARAM_FLAG        = 128const PARAM_SEQUENCE    = 256const PARAM_SEARCH      = 512const PARAM_BODY        = 1024const PARAM_PARTIAL     = 2048const PARAM_EXCLUSIVE   = 4096private static $statusKeywords = (
        'MESSAGES'      => self::PARAM_NO,'RECENT'        => self::PARAM_NO,'UIDNEXT'       => self::PARAM_NO,'UIDVALIDITY'   => self::PARAM_NO,'UNSEEN'        => self::PARAM_NO,1)">
    );
    $searchKeywords = (
        'ALL'           => self::PARAM_NO,'ANSWERED'      => self::PARAM_NO,'BCC'           => 18,1)">// self::PARAM_SINGLE | self::PARAM_STRING,
        'BEFORE'        => 66,1)"> self::PARAM_SINGLE | self::PARAM_DATE,
        'BODY'          => 18,
        'CC'            => 18,
        'DELETED'       => self::PARAM_NO,'DRAFT'         => self::PARAM_NO,'FLAGGED'       => self::PARAM_NO,'FROM'          => 18,
        'HEADER'        => 20,1)"> self::PARAM_PAIR | self::PARAM_STRING,
        'KEYWORD'       => 130,1)"> self::PARAM_SINGLE | self::PARAM_FLAG,
        'LARGER'        => 34,1)"> self::PARAM_SINGLE | self::PARAM_NUMBER,
        'NEW'           => self::PARAM_NO,'NOT'           => 514,1)"> self::PARAM_SINGLE | self::PARAM_SEARCH,
        'OLD'           => self::PARAM_NO,'ON'            => 66,
        'OR'            => 516,1)"> self::PARAM_PAIR | self::PARAM_SEARCH,
        'RECENT'        => self::PARAM_NO,'SEEN'          => self::PARAM_NO,'SENTBEFORE'    => 66,
        'SENTON'        => 66,
        'SENTSINCE'     => 66,
        'SINCE'         => 66,
        'SMALLER'       => 34,
        'SUBJECT'       => 18,
        'TEXT'          => 18,
        'TO'            => 18,
        'UID'           => 258,1)"> self::PARAM_SINGLE | self::PARAM_SEQUENCE,
        'UNANSWERED'    => self::PARAM_NO,'UNDELETED'     => self::PARAM_NO,'UNDRAFT'       => self::PARAM_NO,'UNFLAGGED'     => self::PARAM_NO,'UNKEYWORD'     => 130,
        'UNSEEN'        => self::PARAM_NO,1)">$fetchKeywords = (
        'ALL'           => 4097,1)"> self::PARAM_NO | self::PARAM_EXCLUSIVE,
        'FAST'          => 4097,
        'FULL'          => 4097,
        'BODY'          => 3075,1)"> self::PARAM_NO | self::PARAM_SINGLE | self::PARAM_BODY | self::PARAM_PARTIAL,
        'BODY.PEEK'     => 3074,1)"> self::PARAM_SINGLE | self::PARAM_BODY | self::PARAM_PARTIAL,
        'BODYSTRUCTURE' => self::PARAM_NO,'ENVELOPE'      => self::PARAM_NO,'FLAGS'         => self::PARAM_NO,'INTERNALDATE'  => self::PARAM_NO,'RFC822'        => self::PARAM_NO,'RFC822.HEADER' => self::PARAM_NO,'RFC822.SIZE'   => self::PARAM_NO,'RFC822.TEXT'   => self::PARAM_NO,'UID'           => self::PARAM_NO,1)">private $sock = null$timeout = 120$ts = 0$tagName = 'A'$tagId = 0$capabilities = ();
    $folders = $currentFolder = $currentCommand = $lastSend = ''$lastRecv = ''public function __construct($uri,$timeout = null,1)">$connTimeout = ) {
        $this->sock = new Socket($timeout);        
        $t = intval($timeout);
//        if ($t > 0) {
//            $this->timeout = $t;
//        }
        $this->connect($connTimeout);        
    }
    function __destruct() {
    }

    function connect() {        
        $this->sock->connect();        
        $this->getResponse();
    }
    
     capability() {
        $res = $this->request('capability');
        if (isset($res[0][0]) && $res[0][0] == '*' &&
            $res[0][1]) && strcasecmp($res[0][1],'capability') == 0) {
            for ($i = 2,1)">$n = count($res[0]); $i < $n; ++) {
                $this->capabilities[strtoupper($res[0][$i])] = true;
            }
        }        
    }
    
    function id($data) {
        $this->capabilities['ID'])) {            
            $this->request('id',1)">));            
        }        
    }
    function login($username,1)">$passwordtry {
            $this->request('login',1)">));
        } catch (Exception $exthrow new Exception($ex->getMessage(),1)">$ex->getCode());
        }
    }
    
     logout() {
        $this->request('logout');        
    }
    
    function getList($reference = '',1)">$wildcard = ''$this->request('list',1)">$reference,1)">$wildcard));
        foreach ($res as &$r$r[0]) && $r[0] == '*' && 
                $r[1]) && $r[1],'list') == 0 && 
                $r[4])) {
                $this->folders[$r[4]] = (
                    'id'    => $r[4],'name'  => mb_convert_encoding($r[3],'attr'  => $r[2],1)">
                );
            }
        }
        return folders;
    }
    
    function status($folder,1)">$args = $this->formatArgsForCommand($data,self::$statusKeywords);
        $this->request('status',1)">$args));
        $status = ();
        if (!empty($res)) {            
            ) {
                $r[0] == '*' && 
                    $r[3]) && is_array($r[3])) {
                    $i = 0,1)">$r[3]); $n; $i += 2) {
                        $status[$r[3][$i]] = $i + 1];
                    }
                }
            }
        }
        ;
    }
    function select($folder$this->request('select',1)">)) {
            $r[0] == '*') {
                    $r[2])) {
                        ])) {
                            $i); ) {
                                $r[2][];
                            }
                        } elseif (ctype_digit($r[1])) {
                            $r[2]] = ];
                        } else {
                            $r[1]] = ];
                        }    
                    }
                }
            }
        }
        $this->currentFolder = ;
        function search() {     
        $searchKeywords,1)">);                
        $this->request('search',1)">$ls = $r); ) {
                    $ls[] = $r[];
                }
            }
        }
        $lsfunction fetch($seq,1)">) {                        
        $seqStr = $this->formatSequence($seq$fetchKeywords);                                
        $this->request('fetch',1)">$seqStr,1)">));
        var_dump($res);
        $r[0] == '*' &&
                is_numeric($r[1]) && 
                $r[2]) && $a = ();
                $key = ];
                    if ((($key,'BODY') == 0 && $args['BODY']) && $args['BODY'])) || 
                         ($args['BODY.PEEK']) && $args['BODY.PEEK']))) && 
                        ])) {
                        $key = trim($this->formatRequestArray($key => $i + 1]),1)">$placeHolder,0),'()');
                        $i++;
                    }  {
                        ];
                    }
                    $a[$key] = ];
                }
                $a)) {
                    $ls[;
                }
            }
        }
         nextTag() {
        $this->tagId++return sprintf('%s%d',1)">$this->tagName,1)">tagId);
    }
    function request($cmd,1)">$args = ()) {                
        $this->currentCommand = strtoupper($cmd$tag = nextTag();
        $req = $tag . ' ' . currentCommand;
        
         格式化参数列表
        $strSeqList = )) {
            $argStr = $this->formatRequestArray($args,1)">$strSeqList);                
        }  {                
            $this->formatRequestString();
        }
        $argStr = $this->makeRequest($args,$strSeqList);
        $subReqs = $argStr[0])) {
            $req .= ' ' . $argStr;
             如果参数中包括需要序列化的数据,根据序列化标识{length}将命令拆分成多条
            $strSeqList) && preg_match_all(self::PATTERN_REQUEST_STRING_SEQUENCE,1)">$req,1)">$matches,1)"> PREG_OFFSET_CAPTURE)) {
                $p = 0;
                $matches[0] $m$e = $m[1] + strlen($m[0]);
                    $subReqs[] = substr($p,1)">$e - $p);                    
                    $p = $e;
                }
                );
                 校验序列化标识与需要序列化的参数列表数量是否一致
                $subReqs) != $strSeqList) + 1;
                }
            }
        }
                
        $subReqs 处理单条命令
            $this->sock->writeLine($req);
            $this->lastSend = ;        
            $this->getResponse($tag);
        }  {            
             处理多条命令
            $this->lastSend = ''$subReqs $id => );                          
                $this->lastSend .= ;
                );                
                $res[0][0] == '+'$this->sock->write($strSeqList[$id]);                
                    $this->lastSend .= "\r\n" . ];
                }  {
                     如果服务器端返回其他相应,则定制后续执行
                    break;
                }
            }                
        }
        ;
    }
        
    function formatRequestString($s,&$s = $s$needQuote = false$s[0;
        } elseif ($this->currentCommand == 'ID') {    
             {
             参数包含多行时,需要进行序列化
            strpos(false || ) {                
                $strSeqList[] = sprintf('{%d}',1)">));
            }  {
                 参数包含双引号或空格时,需要将使用双引号括起来
                addcslashes();
                    ;
                }
                if ($needQuotesprintf('"%s"',1)">;
        }
    }
    function formatRequestArray($arr,1)">$strSeqList,1)">$level = -1$arr $k => $v) {
            $isBody = ;
            $supportPartial = $partialStr = ''$this->currentCommand == 'FETCH' 识别是否body命令,是否可以包含<partial>
                $kw = $k);            
                isset(self::$fetchKeywords[$kw]) && (self::$kw] & self::PARAM_BODY) > 0$kw] & self::PARAM_PARTIAL) > 0;
                }
            }                        
            )) {                        
                $supportPartial && $v[self::PARTIAL_PARAM_NAME]) && $v[self::PARTIAL_PARAM_NAME])) {                    
                     处理包含<partial>的命令
                    $v[self::PARTIAL_PARAM_NAME] $spos => $mlen$partialStr =  sprintf('<%d.%d>',1)">$spos,1)">);
                    }                    
                    unset(PARTIAL_PARAM_NAME]);
                }
                $s = $v,1)">$level + 1);
            }  {
                );
            }            
            )) {
                 字典方式需要包含键名
                $k = $k,1)">$isBody$k . ;                    
                }  {
                    $k . ' ' .  包含<partial>
                $supportPartial$s .= $partialStr;
                }
            }
            $a[] = ;
        }
        $level < 0implode(' ',1)">elseif (($level % 2) == 0sprintf('(%s)',1)">sprintf('[%s]',1)">));
        }
    }
    function formatSequence($n == 0return '1:*';            
        } $n == 1$seq[0])) {
                strval(]);
            } $seq $k . ':' . ;
                }
            }
        } implode(',',1)">);
        }
    }
    function formatArgsForCommand(&$fields,1)">$asList = $data ) {            
             无值参数
                $name = $fields[$name 对于排他性属性,直接返回
                    if (($name] & self::PARAM_EXCLUSIVE) > 0) {
                        $name] & self::PARAM_NO) > 0) {                
                        $args[] = ;
                    }
                }
            } $k == self::SEQUENCE_PARAM_NAME) {
                 序列
                );                
            } ])) {
                    $paramType = ];                    
                     格式化参数类型
                    $paramType & self::PARAM_DATE) > 0$v = date('j-M-Y',1)">);
                    } $paramType & self::PARAM_SEQUENCE) > 0$v = );
                    }                        

                     根据参数定义拼组参数列表
                    $paramType & self::PARAM_SINGLE) > 0 单值参数
                        $asList) {
                            ;
                            ;
                        } $args[$name] = ;
                        }
                    } $paramType & self::PARAM_PAIR) > 0 键值对参数
                        )) {
                            $v $x => $y$pk = $x;
                                $pv = ;
                                ;
                            }
                        } $pv = '';
                        }
                        $pk$pv$name] = $pk => );
                        }
                    } $paramType & self::PARAM_LIST) > 0 列表参数
                        ;
                            $paramType & self::PARAM_NO) > 0 无值参数
                        ;
                    }
                }
            }
        }
        function getResponse($tag = $r = ();
        $readMore = ;  
        while ($readMore$ln = $this->sock->readLine());            
            $ln[0 connection closed or read empty string,throw exception to avoid dead loop and reconnect
                Exception('read response Failed');
            }
            
            $matches = $strSeqKey = $strSeq = preg_match(self::PATTERN_RESPONSE_STRING_SEQUENCE,1)">$ln,1)">$matches)) {
                $strSeqKey = $matches[0];
                $this->readSequence($strSeq,1)">$matches[1]);
            }
            $this->lastRecv = $ln;
            
             区分处理不同种响应
            switch (]) {
                case '*':
                    $r[] = $this->parseLine($strSeqKey,1)">$strSeq);                                        
                    if (!;
                    }
                    case $this->tagName:
                    );
                     {
                        
                    }
                    case '+':
                    ;
                    default:
                    ;
            }                        
        }        
        
        var_dump($this->lastSend,$this->lastRecv);
        
        // 无响应数据
        Exception('no response');
        }
                                                
        $last = $r[$r) - 1];
        $last[0]) && $last[0] == '+' 继续发送请求数据
        } $last[0]) || $last[0],1)">$tag) != 0) {                    
                    Exception('tag no match');
                }           
            } Exception('untag no match');
                }
            }
            $last[1 处理响应出错的情况
                $last[1],'bad') == 0) {        
                    Exception($last));
                } ));
                }
            }
            $this->currentCommand = null;
        }
        
        ;
    }
    
    function readSequence(&$seqLength 对于字符串序列,读取完整内容后再拼接响应        
        $readLen = 0;
        $st = microtime( 网络请求多次读取字符串序列内容,直到读好为止
        $readLen < $sb = $this->sock->read($seqLength - $readLen);
            $sb[0$strSeq .= $sb$readLen = );
            }                    
            if ((true) - $st) > timeout) {
                Exception('read sequence timeout');
            }
        }
         读取字符串序列后的剩余命令
        $leftLn = rtrim(readLine());
        $ln = $ln . $leftLnfunction parseLine($p =& $stack = $token = ''$escape = $inQuote = $ln); $ch = $ln[];
            $ch == '"' 处理双引号括起的字符串
                $inQuote;
                } ;
                }
            }  对于括起的字符串,处理双引号转义
                $ch == '\\'$escape && $i + 1]) && $i + 1] == '"') {               
                        $token .= '"';
                        $token .= $ch$escape = !$escape;
                    }                    
                } $ch == ' ' || 
                $ch == '(' || $ch == ')' || 
                $ch == '[' || $ch == ']' 处理子列表
                $token[0 将字符串序列标识:{length},替换为真实字符串
                    $strSeqKey && $token == $strSeqKey$p[] = $token;
                    }
                    ;
                }                
                $ch == '[') {                    
                    $p[] = ();
                    $stack[] =& ;
                    $p[$p) - 1];                                        
                } $ch == ')' || ) {        
                    $stack[$stack) - 1array_pop($stack);
                }
            }  {                
                 处理字符串字面量
                ;
            }            
        }
        ])) {
             将字符串序列标识:{length},替换为真实字符串
            ;
            } ;
            }
        }
        ;
    }
}

 end of PHP

 

socket.PHP

<? Socket{
    const DEFAULT_READ_SIZE = 8192const CRTL = "\r\n"$uri = $connected = ){
        $this->uri = $uri$this->timeout = $this->formatTimeout();
    }

    $retryTimes = ){
        connected) {
            close();
        }

        $connTimeout = $timeout,1)">timeout);
        intval($retryTimes$retryTimes < 1$retryTimes = 1$i = 0; $retryTimes; ++stream_socket_client(
                $this->uri,1)">$errno,1)">$error,1)">sock) {
                sock) {

        }
        stream_set_timeout($this->sock,1)">$this->connected = ;
    }

    function read($sizeassert(connected);

        $buf = fread($buf === handleReadError();
        }

        $buf readLine(){
        connected);
        $buf = ''while (fgets(DEFAULT_READ_SIZE);
            $s === checkReadTimeout();
                ;
            }
            $n$buf .= $s[$n - 1] == "\n";
            }
        }

         readAll(){
        handleReadError();
            }

            ;
            }

            ;
        }

        function write($w = 0$w < $w,1)">DEFAULT_READ_SIZE);
            fwrite(close();
            }
            $w += function writeLine($this->write($s . self::CRTL);
    }
     close() {
        connected) {
            fclose(sock);
            function formatTimeout($default = $t = $t <= 0$defaultini_get('default_socket_timeout'$t = $t checkReadTimeout(){
        $Meta = stream_get_Meta_data(sock);
        $Meta['timed_out'close();
        }
    }

     handleReadError(){
        checkReadTimeout();
        close();
    }
}

 

猜你在找的PHP相关文章