2012-08-15 7 views
6

Gibt es eine verfügbare Implementierung von POP3/IMAP-Server in PHP?IMAP- oder POP3-Server in PHP implementiert

Ich bearbeite meinen E-Mail-Service mit sendgrid. Ich werde die Nachrichten auf meinem Server unter Verwendung von Dateien/db/was auch immer speichern und jetzt möchte ich vollen POP3 oder IMAP (vorzugsweise) Zugang für meine Benutzer zu ihrem Postfach zur Verfügung stellen. Gibt es eine solche Implementierung in PHP? Oder gibt es eine andere Möglichkeit, POP3/IMAP in der verteilten Umgebung von Windows Azure auszuführen (vorausgesetzt, die Postfächer sind in freigegebenen Blobs/Tabellen/db gespeichert)?

+2

Möglicherweise gibt es eine Implementierung von diesem in PHP, aber wenn es für die Liebe Gottes ist, verwenden Sie es nicht! Abgesehen von Shell-Skripten ist PHP die schlechteste Sprache, die mir dafür zur Verfügung steht. Wenn Sie etwas in einer Sprache möchten, die Webentwickler verstehen, sehen Sie sich Node.js an. – DaveRandom

+0

@DaveRandom, Sie sind verdammt richtig ... Allerdings verwendet meine App PHP und ich bin auch durch die Optionen von Windows Azure-Plattform beschränkt. –

+3

Nun POP3 und IMAP sind nicht besonders komplizierte Protokolle (je nachdem, was Sie unterstützen möchten) und könnte in PHP ziemlich einfach implementiert werden, aber Nebenläufigkeit ist ein großes Problem in PHP, weil es Threading nicht unterstützt und sogar Forking Forking ist. ... ähm ... naja, seien wir nett und sagen * herausfordernd * unter Windows zu implementieren. Auch in Bezug auf die Effizienz wäre dies schockierend. Können Sie Node.js nicht installieren? Ich habe bereits 2 POP3- und 1 IMAP-Server mit netten einfach zu bedienenden APIs implementiert. – DaveRandom

Antwort

10

Nun, nur um zu zeigen, dass es tatsächlich möglich ist, einen POP3-Server in PHP zu schreiben, hier ist es. Der Server führt keine Authentifizierung durch - oder so ziemlich alles andere. Es sendet einfach immer wieder die gleiche Nachricht. Aber es funktioniert. Thunderbird konnte Nachrichten von ihm abrufen. Total nutzlos, aber irgendwie cool.

Mein Setup ist Apache 2 unter Windows mit 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, was ist die Quelle? Hast du es selbst erstellt? –

+2

Ja, ich habe es selbst geschrieben. – cleong

+1

Wenn Sie auf einem Nicht-Windows-Host arbeiten, können Sie [PCNTL] (http://php.net/manual/en/pcntl.example.php) verwenden, um einen neuen Prozess zu erstellen. – Xeoncross