Сервер IMAP или POP3, реализованный в PHP

Есть ли доступная реализация сервера POP3 / IMAP в PHP?

Я обрабатываю свой почтовый сервис с помощью sendgrid . Я собираюсь хранить сообщения на своем сервере с помощью файлов / db / whatever, и теперь я хотел бы предоставить полный доступ к POP3 или IMAP (предпочтительный) для своих пользователей в свой почтовый ящик. Есть ли такая реализация в PHP? Или есть ли другая возможность запускать POP3 / IMAP в распределенной среде Windows Azure (если у меня есть почтовые ящики, хранящиеся в общих блоках / таблицах / db)?

Ну, просто чтобы показать, что на самом деле можно писать POP3-сервер в PHP, вот оно. Сервер не выполняет аутентификации – или почти ничего. Он просто продолжает отправлять одно и то же сообщение снова и снова. Но это работает. Thunderbird смог извлечь из него сообщения. Совершенно бесполезно, но вроде круто.

Моя настройка – Apache 2 в Windows с PHP 5.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; } } ?>