2012-08-15 35 views
6

Có bất kỳ triển khai nào có sẵn của máy chủ POP3/IMAP trong PHP không?Máy chủ IMAP hoặc POP3 được triển khai trong PHP

Tôi đang xử lý dịch vụ e-mail của mình bằng cách sử dụng sendgrid. Tôi sẽ lưu trữ các tin nhắn trên máy chủ của tôi bằng cách sử dụng các tập tin/db/bất cứ điều gì và bây giờ tôi muốn cung cấp đầy đủ POP3 hoặc IMAP (thích hợp hơn) truy cập cho người dùng của tôi vào hộp thư của họ. Có thực hiện như vậy trong PHP? Hoặc là có bất kỳ khả năng khác để chạy POP3/IMAP trong môi trường phân tán của Windows Azure (giả sử tôi có hộp thư được lưu trữ trong chia sẻ blobs/bảng/db)?

+2

Có thể thực hiện điều này trong PHP, nhưng nếu có tình yêu của thần thì không sử dụng nó! Ngoài các kịch bản lệnh shell, PHP là ngôn ngữ tồi tệ nhất mà tôi có thể nghĩ đến khi thực hiện việc này. Nếu bạn muốn một cái gì đó trong một ngôn ngữ mà các nhà phát triển web hiểu, hãy nhìn vào Node.js. – DaveRandom

+0

@DaveRandom, bạn đang chết tiệt ... Tuy nhiên, ứng dụng của tôi sử dụng PHP và tôi cũng bị giới hạn bởi các tùy chọn được cung cấp bởi nền tảng Windows Azure. –

+3

Cũng POP3 và IMAP không phải là giao thức phức tạp đặc biệt (tùy thuộc vào những gì bạn muốn hỗ trợ) và có thể được triển khai trong PHP khá dễ dàng, nhưng đồng thời là một vấn đề lớn trong PHP vì nó không hỗ trợ luồng và thậm chí là xử lý là .. . err ... tốt, hãy tử tế và nói * thách thức * để triển khai trên Windows. Ngoài ra, hiệu quả khôn ngoan này sẽ gây sốc. Không có cách nào bạn có thể cài đặt Node.js? Poking xung quanh Google Tôi đã tìm thấy 2 POP3 và 1 máy chủ IMAP được triển khai với các API dễ sử dụng. – DaveRandom

Trả lời

10

Vâng, chỉ để chứng minh rằng thực tế là có thể viết một máy chủ POP3 bằng PHP, ở đây nó được. Máy chủ không xác thực - hoặc nhiều thứ khác. Nó chỉ tiếp tục gửi đi cùng một tin nhắn. Nhưng nó đã có tác dụng. Thunderbird có thể truy xuất tin nhắn từ nó. Hoàn toàn vô dụng, nhưng rất tuyệt.

Thiết lập của tôi là Apache 2 trên Windows với 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, nguồn gốc là gì? Bạn đã tự mình tạo ra nó chưa? –

+2

Vâng, tôi đã tự viết. – cleong

+1

Nếu bạn đang ở trên máy chủ không có cửa sổ, bạn có thể sử dụng [PCNTL] (http://php.net/manual/en/pcntl.example.php) để chia rẽ một quy trình mới. – Xeoncross

Các vấn đề liên quan