2012-08-15 13 views
6

PHP'de POP3/IMAP sunucusunun kullanılabilir bir uygulaması var mı?PHP'de uygulanan IMAP veya POP3 sunucusu

sendgrid'u kullanarak e-posta hizmetimi yönetiyorum. Mesajları sunucumda dosyaları/db/neyse kullanarak saklayacağım ve şimdi kullanıcılara posta kutularına tam POP3 veya IMAP (tercih edilen) erişimi sağlamak istiyorum. PHP'de böyle bir uygulama var mı? Ya da Windows Azure'un dağıtılmış ortamında POP3/IMAP'ı çalıştırmanın başka bir olasılığı var mı (paylaşılan bloblarda/tablolarda/db'de saklanan posta kutularını varsayarak)?

+2

PHP'de bunun bir uygulaması olabilir, ancak eğer tanrı sevgisi varsa bunu kullanmayın! Kabuk betikleri dışında PHP, bunu yapmak için düşünebileceğim en kötü dil hakkındadır. Web geliştiricilerinin anlayacağı bir dilde bir şey istiyorsanız, Node.js. – DaveRandom

+0

@DaveRandom, haklısın ... Ancak, uygulamam PHP kullanıyor ve ayrıca Windows Azure platformu tarafından sağlanan seçenekler tarafından da sınırlandırılıyor. –

+3

Kuyu POP3 ve IMAP özellikle karmaşık protokoller değildir (ne yapmak istediğinize bağlı olarak) ve PHP'de oldukça kolay bir şekilde uygulanabilirler, ancak eşzamanlılık PHP'de büyük bir sorundur çünkü iş parçacığı desteklemez ve hatta forking işlemek bile değildir. err ... iyi, hadi kibar olun ve Windows üzerinde uygulamak için * zorlu * diyelim. Ayrıca, verimlilik açısından bu şok edici olurdu. Node.js'yi kurmanın hiçbir yolu yok mu? Google'da dolaşmak Çok kolay kullanımlı API'lar ile 2 POP3 ve 1 IMAP sunucusu uyguladım. – DaveRandom

cevap

10

Aslında PHP'de bir POP3 sunucusunun yazılmasının mümkün olduğunu göstermek için, işte burada. Sunucu kimlik doğrulaması yapmıyor veya başka bir şey yapmıyor. Aynı mesajı tekrar tekrar göndermeye devam ediyor. Ama işe yarıyor. Thunderbird ondan mesajlar alabildi. Tamamen işe yaramaz, ama biraz havalı.

Kurulumum, PHP 5.2 ile Windows'ta Apache 2'dir.

<?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, kaynak nedir? Bunu kendin mi yarattın? –

+2

Evet, kendim yazdım. – cleong

+1

Windows olmayan bir ev sahibi olsaydınız, yeni bir işlemi engellemek için [PCNTL] (http://php.net/manual/en/pcntl.example.php) kullanabilirsiniz. – Xeoncross

İlgili konular