2012-08-15 28 views
6

PHPにはPOP3/IMAPサーバの実装がありますか?PHPで実装されたIMAPまたはPOP3サーバ

sendgridを使用して自分のメールサービスを処理しています。私はファイル/ db/whateverを使用して私のサーバーにメッセージを保存するつもりです。そして、私は自分のメールボックスに完全なPOP3またはIMAP(望ましい)アクセスを提供したいと思います。 PHPにそのような実装がありますか?または、Windows Azureの分散環境でPOP3/IMAPを実行する他の可能性があります(メールボックスを共有のblob/tables/dbに格納していると仮定します)。

+2

PHPの実装があるかもしれませんが、神の愛のためにそれが使用されている場合は!シェルスクリプトとは別に、PHPはこれを行うために私が考えることができる最悪の言語です。 Web開発者が理解できる言語で何かをしたいのなら、Node.jsを見てください。 – DaveRandom

+0

@DaveRandom、あなたはまあまあです...しかし、私のアプリはPHPを使用しており、Windows Azureプラットフォームで提供されるオプションによっても制限されています。 –

+3

さて、POP3とIMAPは特に複雑なプロトコルではなく(サポートしたいものに依存します)、PHPでかなり簡単に実装できますが、スレッド処理をサポートしていないため、並行処理はPHPの大きな問題です。 。err ...うーん、親切にして、Windows上で実装することを挑戦してみましょう。また、効率的にはこれは衝撃的です。 Node.jsをインストールする方法はありませんか?私はすでに2つのPOP3と1つのIMAPサーバーが使いやすいAPIで実装されていることがわかりました。 – DaveRandom

答えて

10

まあ、実際には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: [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

ええ、元は何ですか?自分で作成しましたか? –

+2

ええ、私はそれを自分で書きました。 – cleong

+1

Windows以外のホストにいる場合は、[PCNTL](http://php.net/manual/en/pcntl.example.php)を使用して新しいプロセスをフォークすることができます。 – Xeoncross

関連する問題