7

PHP 中是否有任何可用的 POP3/IMAP 服务器实现?

我正在使用sendgrid处理我的电子邮件服务。我将使用 files/db/whatever 将邮件存储在我的服务器上,现在我想为我的用户提供对其邮箱的完整 POP3 或 IMAP(首选)访问权限。PHP中有这样的实现吗?或者是否有任何其他可能在 Windows Azure 的分布式环境中运行 POP3/IMAP(假设我将邮箱存储在共享 blobs/tables/db 中)?

4

1 回答 1

12

好吧,只是为了表明实际上可以用 PHP 编写 POP3 服务器,就是这样。服务器不进行身份验证——或者几乎没有其他任何事情。它只是一遍又一遍地发送相同的消息。但它有效。Thunderbird 能够从中检索消息。完全没用,但有点酷。

我的设置是带有 PHP 5.2 的 Windows 上的 Apache 2。

<?php

// echo something so fopen() would return
header("Content-type: text/plain");
echo "OK\n";
flush();

// listen for incoming connection
$listen_socket = socket_create_listen(110, 1);
$r = $w = $e = array($listen_socket);
$n = socket_select($r, $w, $e, 120);
$client_socket = ($n == 1) ? socket_accept($listen_socket) : null;
socket_close($listen_socket);

// spawn copy of myself
$internal_url = "http://{$_SERVER['HTTP_HOST']}:{$_SERVER['SERVER_PORT']}{$_SERVER['SCRIPT_NAME']}";
$stream_context_options = array (
    'http' => array (
        'method' => 'GET',
        'timeout' => 1
    )
);
$context = stream_context_create($stream_context_options);
if($f = fopen($internal_url, "rb", 0, $context)) {
    fclose($f);
}

if(!$client_socket) {
    // timed out
    exit;
}

// start handling the session
$read_buffer = "";
$write_buffer = "+OK POP3 server ready\r\n";
$active = true;

$messages = array(
    "From: webmaster@example.com\r\nSubject: This is a test\r\n\r\nHello world!\r\n"
);


$idle_start = time();
while(true) {
    $r = $w = $e = array($client_socket);
    $n = socket_select($r, $w, $e, 60);
    if($n) {
        if($r) {
            // read from the socket
            $read_buffer .= socket_read($client_socket, 128);
            $idle_start = time();
        }
        if($w) {
            if($write_buffer) {
                // write to the socket
                $written = socket_write($client_socket, $write_buffer);
                $write_buffer = substr($write_buffer, $written);
                $idle_start = time();
            } else if($active) {
                $now = time();
                $idle_time = $now - $idle_start;
                if($idle_time > 10) {
                    // exit if nothing happened for 10 seconds
                    break;
                } else if($idle_time > 2) {
                    // start napping when the client is too slow
                    sleep(1);
                }
            } else {
                break;
            }
        }
        if($e) {
            break;
        }
        if($read_buffer) {
            if(preg_match('/(.*?)(?:\s+(.*?))?[\r\n]+/', $read_buffer, $matches)) {
                $read_buffer = substr($read_buffer, strlen($matches[0]));
                $command = $matches[1];
                $argument = $matches[2];
                switch($command) {
                    case 'USER':
                        $username = $argument;
                        $write_buffer .= "+OK $username is welcome here\r\n";
                        break;
                    case 'PASS':
                        $message_count = count($messages);
                        $write_buffer .= "+OK mailbox has $message_count message(s)\r\n";
                        break;
                    case 'QUIT': 
                        $write_buffer .= "+OK POP3 server signing off\r\n";
                        $active = false;
                        break;
                    case 'STAT':
                        $message_count = count($messages);
                        $mailbox_size = 0;
                        foreach($messages as $message) {
                            $mailbox_size += strlen($message);
                        }
                        $write_buffer .= "+OK $message_count $mailbox_size\r\n";
                        break;
                    case 'LIST':
                        $start_index = (int) $argument;
                        $message_count = count($messages) - $start_index;
                        $total_size = 0;
                        for($i = $start_index; $i < count($messages); $i++) {
                            $total_size += strlen($messages[$i]);
                        }
                        $write_buffer .= "+OK $message_count messages ($total_size octets)\r\n";
                        for($i = $start_index; $i < count($messages); $i++) {
                            $message_id = $i + 1;
                            $message_size = strlen($messages[$i]);
                            $write_buffer .= "$message_id $message_size\r\n";
                        }
                        $write_buffer .= ".\r\n";
                        break;
                    case 'RETR':
                        $message_id = (int) $argument;
                        $message = $messages[$message_id - 1];
                        $message_size = strlen($message);
                        $write_buffer .= "+OK $message_size octets\r\n";
                        $write_buffer .= "$message\r\n";
                        $write_buffer .= ".\r\n";
                        break;
                    case 'DELE':
                        $write_buffer .= "+OK\r\n";
                        break;
                    case 'NOOP':
                        $write_buffer .= "+OK\r\n";
                        break;
                    case 'LAST':
                        $message_count = count($messages) - $start_index;
                        $write_buffer .= "+OK $message_count\r\n";
                        break;
                    case 'RSET':
                        $write_buffer .= "+OK\r\n";
                        break;
                    default:
                        $write_buffer .= "-ERR Unknown command '$command'\r\n";
                }
            }
        }
    } else {
        break;
    }
}

?>
于 2012-08-15T16:49:41.693 回答