📄 imap.php
字号:
<?php/** * Zend Framework * * LICENSE * * This source file is subject to version 1.0 of the Zend Framework * license, that is bundled with this package in the file LICENSE.txt, and * is available through the world-wide-web at the following URL: * http://framework.zend.com/license/new-bsd. If you did not receive * a copy of the Zend Framework license and are unable to obtain it * through the world-wide-web, please send a note to license@zend.com * so we can mail you a copy immediately. * * @category Zend * @package Zend_Mail * @subpackage Protocol * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License * @version $Id: Imap.php 8928 2008-03-20 19:41:41Z thomas $ *//** * @category Zend * @package Zend_Mail * @subpackage Protocol * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License */class Zend_Mail_Protocol_Imap{ /** * socket to imap server * @var resource|null */ protected $_socket; /** * counter for request tag * @var int */ protected $_tagCount = 0; /** * Public constructor * * @param string $host hostname of IP address of IMAP server, if given connect() is called * @param int|null $port port of IMAP server, null for default (143 or 993 for ssl) * @param bool $ssl use ssl? 'SSL', 'TLS' or false * @throws Zend_Mail_Protocol_Exception */ function __construct($host = '', $port = null, $ssl = false) { if ($host) { $this->connect($host, $port, $ssl); } } /** * Public destructor */ public function __destruct() { $this->logout(); } /** * Open connection to POP3 server * * @param string $host hostname of IP address of POP3 server * @param int|null $port of IMAP server, default is 143 (993 for ssl) * @param string|bool $ssl use 'SSL', 'TLS' or false * @return string welcome message * @throws Zend_Mail_Protocol_Exception */ public function connect($host, $port = null, $ssl = false) { if ($ssl == 'SSL') { $host = 'ssl://' . $host; } if ($port === null) { $port = $ssl === 'SSL' ? 993 : 143; } $this->_socket = @fsockopen($host, $port); if (!$this->_socket) { /** * @see Zend_Mail_Protocol_Exception */ require_once 'Zend/Mail/Protocol/Exception.php'; throw new Zend_Mail_Protocol_Exception('cannot connect to host'); } if (!$this->_assumedNextLine('* OK')) { /** * @see Zend_Mail_Protocol_Exception */ require_once 'Zend/Mail/Protocol/Exception.php'; throw new Zend_Mail_Protocol_Exception('host doesn\'t allow connection'); } if ($ssl === 'TLS') { $result = $this->requestAndResponse('STARTTLS'); $result = $result && stream_socket_enable_crypto($this->_socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT); if (!$result) { /** * @see Zend_Mail_Protocol_Exception */ require_once 'Zend/Mail/Protocol/Exception.php'; throw new Zend_Mail_Protocol_Exception('cannot enable TLS'); } } } /** * get the next line from socket with error checking, but nothing else * * @return string next line * @throws Zend_Mail_Protocol_Exception */ protected function _nextLine() { $line = @fgets($this->_socket); if ($line === false) { /** * @see Zend_Mail_Protocol_Exception */ require_once 'Zend/Mail/Protocol/Exception.php'; throw new Zend_Mail_Protocol_Exception('cannot read - connection closed?'); } return $line; } /** * get next line and assume it starts with $start. some requests give a simple * feedback so we can quickly check if we can go on. * * @param string $start the first bytes we assume to be in the next line * @return bool line starts with $start * @throws Zend_Mail_Protocol_Exception */ protected function _assumedNextLine($start) { $line = $this->_nextLine(); return strpos($line, $start) === 0; } /** * get next line and split the tag. that's the normal case for a response line * * @param string $tag tag of line is returned by reference * @return string next line * @throws Zend_Mail_Protocol_Exception */ protected function _nextTaggedLine(&$tag) { $line = $this->_nextLine(); // seperate tag from line list($tag, $line) = explode(' ', $line, 2); return $line; } /** * split a given line in tokens. a token is literal of any form or a list * * @param string $line line to decode * @return array tokens, literals are returned as string, lists as array * @throws Zend_Mail_Protocol_Exception */ protected function _decodeLine($line) { $tokens = array(); $stack = array(); /* We start to decode the response here. The unterstood tokens are: literal "literal" or also "lit\\er\"al" {bytes}<NL>literal (literals*) All tokens are returned in an array. Literals in braces (the last unterstood token in the list) are returned as an array of tokens. I.e. the following response: "foo" baz {3}<NL>bar ("f\\\"oo" bar) would be returned as: array('foo', 'baz', 'bar', array('f\\\"oo', 'bar')); // TODO: add handling of '[' and ']' to parser for easier handling of response text */ // replace any trailling <NL> including spaces with a single space $line = rtrim($line) . ' '; while (($pos = strpos($line, ' ')) !== false) { $token = substr($line, 0, $pos); while ($token[0] == '(') { array_push($stack, $tokens); $tokens = array(); $token = substr($token, 1); } if ($token[0] == '"') { if (preg_match('%^"((.|\\\\|\\")*?)" *%', $line, $matches)) { $tokens[] = $matches[1]; $line = substr($line, strlen($matches[0])); continue; } } if ($token[0] == '{') { $endPos = strpos($token, '}'); $chars = substr($token, 1, $endPos - 1); if (is_numeric($chars)) { $token = ''; while (strlen($token) < $chars) { $token .= $this->_nextLine(); } $line = ''; if (strlen($token) > $chars) { $line = substr($token, $chars); $token = substr($token, 0, $chars); } else { $line .= $this->_nextLine(); } $tokens[] = $token; $line = trim($line) . ' '; continue; } } if ($stack && $token[strlen($token) - 1] == ')') { // closing braces are not seperated by spaces, so we need to count them $braces = strlen($token); $token = rtrim($token, ')'); // only count braces if more than one $braces -= strlen($token) + 1; // only add if token had more than just closing braces if ($token) { $tokens[] = $token; } $token = $tokens; $tokens = array_pop($stack); // special handline if more than one closing brace while ($braces-- > 0) { $tokens[] = $token; $token = $tokens; $tokens = array_pop($stack); } } $tokens[] = $token; $line = substr($line, $pos + 1); } // maybe the server forgot to send some closing braces while ($stack) { $child = $tokens; $tokens = array_pop($stack); $tokens[] = $child; } return $tokens; } /** * read a response "line" (could also be more than one real line if response has {..}<NL>) * and do a simple decode * * @param array|string $tokens decoded tokens are returned by reference, if $dontParse * is true the unparsed line is returned here * @param string $wantedTag check for this tag for response code. Default '*' is * continuation tag. * @param bool $dontParse if true only the unparsed line is returned $tokens * @return bool if returned tag matches wanted tag * @throws Zend_Mail_Protocol_Exception */ public function readLine(&$tokens = array(), $wantedTag = '*', $dontParse = false) { $line = $this->_nextTaggedLine($tag); if (!$dontParse) { $tokens = $this->_decodeLine($line); } else { $tokens = $line; } // if tag is wanted tag we might be at the end of a multiline response return $tag == $wantedTag; } /** * read all lines of response until given tag is found (last line of response) * * @param string $tag the tag of your request * @param string|array $filter you can filter the response so you get only the * given response lines * @param bool $dontParse if true every line is returned unparsed instead of * the decoded tokens * @return null|bool|array tokens if success, false if error, null if bad request * @throws Zend_Mail_Protocol_Exception */ public function readResponse($tag, $dontParse = false) { $lines = array(); while (!$this->readLine($tokens, $tag, $dontParse)) { $lines[] = $tokens; } if ($dontParse) { // last to chars are still needed for response code $tokens = array(substr($tokens, 0, 2)); } // last line has response code if ($tokens[0] == 'OK') { return $lines ? $lines : true; } else if ($tokens[0] == 'NO'){ return false; } return null; } /** * send a request * * @param string $command your request command * @param array $tokens additional parameters to command, use escapeString() to prepare * @param string $tag provide a tag otherwise an autogenerated is returned * @return null * @throws Zend_Mail_Protocol_Exception */ public function sendRequest($command, $tokens = array(), &$tag = null) { if (!$tag) { ++$this->_tagCount; $tag = 'TAG' . $this->_tagCount; } $line = $tag . ' ' . $command; foreach ($tokens as $token) { if (is_array($token)) { if (@fputs($this->_socket, $line . ' ' . $token[0] . "\r\n") === false) { /** * @see Zend_Mail_Protocol_Exception */ require_once 'Zend/Mail/Protocol/Exception.php'; throw new Zend_Mail_Protocol_Exception('cannot write - connection closed?'); } if (!$this->_assumedNextLine('+ OK')) { /** * @see Zend_Mail_Protocol_Exception */ require_once 'Zend/Mail/Protocol/Exception.php'; throw new Zend_Mail_Protocol_Exception('cannot send literal string'); } $line = $token[1]; } else { $line .= ' ' . $token; } } if (@fputs($this->_socket, $line . "\r\n") === false) { /** * @see Zend_Mail_Protocol_Exception */ require_once 'Zend/Mail/Protocol/Exception.php'; throw new Zend_Mail_Protocol_Exception('cannot write - connection closed?'); } } /** * send a request and get response at once * * @param string $command command as in sendRequest() * @param array $tokens parameters as in sendRequest() * @param bool $dontParse if true unparsed lines are returned instead of tokens * @return mixed response as in readResponse() * @throws Zend_Mail_Protocol_Exception */ public function requestAndResponse($command, $tokens = array(), $dontParse = false) { $this->sendRequest($command, $tokens, $tag); $response = $this->readResponse($tag, $dontParse); return $response; } /** * escape one or more literals i.e. for sendRequest * * @param string|array $string the literal/-s * @return string|array escape literals, literals with newline ar returned * as array('{size}', 'string'); */ public function escapeString($string) { if (func_num_args() < 2) { if (strpos($string, "\n") !== false) { return array('{' . strlen($string) . '}', $string); } else { return '"' . str_replace(array('\\', '"'), array('\\\\', '\\"'), $string) . '"'; } } $result = array(); foreach (func_get_args() as $string) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -