2012-08-15 8 views
6

Czy jest dostępna jakakolwiek implementacja serwera POP3/IMAP w PHP?Serwer IMAP lub POP3 zaimplementowany w PHP

Obsługuję moją usługę e-mail za pomocą sendgrid. Będę przechowywać wiadomości na moim serwerze za pomocą plików/db/cokolwiek, a teraz chciałbym zapewnić pełny dostęp POP3 lub IMAP (najlepiej) dla moich użytkowników do ich skrzynek pocztowych. Czy jest taka implementacja w PHP? Czy istnieje jakakolwiek inna możliwość uruchomienia POP3/IMAP w rozproszonym środowisku Windows Azure (zakładając, że mam skrzynki pocztowe przechowywane we współdzielonych obszarach blobs/tabelach/db)?

+2

Może to być implementacja w PHP, ale jeśli istnieje miłość Boga, nie używaj go! Oprócz skryptów powłoki, PHP jest najgorszym językiem, jaki mogę wymyślić. Jeśli chcesz czegoś w języku zrozumiałym dla twórców stron, spójrz na Node.js. – DaveRandom

+0

@DaveRandom, masz cholerną rację ... Jednak moja aplikacja używa PHP i jestem również ograniczony opcjami dostępnymi na platformie Windows Azure. –

+3

Cóż, POP3 i IMAP nie są szczególnie skomplikowanymi protokołami (w zależności od tego, co chcemy wspierać) i mogą być dość łatwo zaimplementowane w PHP, ale współbieżność jest dużym problemem w PHP, ponieważ nie obsługuje wątków, a nawet proces rozwidlania jest ... błądz ... no cóż, bądźmy życzliwi i powiedzmy * wymagający * do wdrożenia w systemie Windows. Również pod względem wydajności byłoby to szokujące. Czy nie ma możliwości zainstalowania Node.js? Pokonanie Google Znalazłem już 2 serwery POP3 i 1 IMAP zaimplementowane z łatwymi w użyciu interfejsami API. – DaveRandom

Odpowiedz

10

Cóż, tylko po to, aby pokazać, że faktycznie można napisać serwer POP3 w PHP, oto on. Serwer nie uwierzytelnia się - lub prawie wszystko. Po prostu ciągle przesyła tę samą wiadomość. Ale działa. Thunderbird był w stanie pobrać z niego wiadomości. Całkowicie bezużyteczny, ale trochę fajny.

Moja konfiguracja to Apache 2 na Windowsie z 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: [email protected]\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; 
    } 
} 

?> 
+0

Yeh, jakie jest źródło? Stworzyłeś go sam? –

+2

Tak, sam to napisałem. – cleong

+1

Jeśli byłeś na hoście bez systemu Windows, możesz użyć [PCNTL] (http://php.net/manual/en/pcntl.example.php) do rozwidlenia nowego procesu. – Xeoncross

Powiązane problemy