2012-04-24 27 views
9

Tôi đang tìm cách tải xuống toàn bộ dữ liệu email thô (bao gồm tệp đính kèm), tương tự như những gì bạn nhận được bằng cách nhấp vào "Hiển thị Bản gốc" trong Gmail.Làm thế nào để nhận dữ liệu email thô với phần mở rộng imap?

Hiện nay, tôi có thể nhận được header liệu và một số bộ phận của cơ thể mail bằng mã này:

$this->MailBox = imap_open($mailServer, $userName, $password, OP_SILENT); 
... 
$email->RawEmail = imap_fetchbody($this->MailBox, $msgNo, "0"); 
$email->RawEmail .= "\n".imap_fetchbody($this->MailBox, $msgNo, "1"); 

Ngoài ra tôi biết rằng việc thay đổi các tham số thứ 3 của imap_fetchbody có thể trở lại tập tin đính kèm được mã hóa. Đoán tôi cần một vòng lặp ở đây để có được phần email thô một phần, nhưng điều kiện để ngăn chặn vòng lặp là gì?

Có cách nào dễ dàng để nhận toàn bộ email cùng một lúc không?

Mọi trợ giúp sẽ được đánh giá cao.

Trả lời

5

Nếu bạn muốn lấy tất cả, bạn cần phải lấy

Vì tin nhắn có thể có nhiều nội dung, bạn cần xử lý từng phần sau phần kia. Để giảm tải cho máy chủ, hãy sử dụng tùy chọn FT_PREFETCHTEXT cho imap_fetchheader. Một số ví dụ code about imap_fetchstructure in another answer cho thấy việc xử lý kết nối imap và lặp qua các phần của một thông điệp đã được thông qua đóng gói.

+1

cuộn xuống, sử dụng '' imap_fetchbody ($ imap_stream, $ msg_num, "") '' đơn giản hơn nhiều và hoạt động giống như một sự quyến rũ! –

+0

Tôi cũng không chắc chắn nếu điều này trả lời câu hỏi vì nó sẽ không nhận được ranh giới. – MrMesees

8

Câu trả lời của hakre là quá tải, nếu bạn không thực sự quan tâm đến cấu trúc thì bạn sẽ không cần imap_fetchstructure.

Đối với 'Nguồn Hiển thị' đơn giản, bạn chỉ cần imap_fetchheaderimap_body.

Ví dụ:

$conn = imap_open('{'."$mailServer:$port/pop3}INBOX", $userName, $password, OP_SILENT && OP_READONLY); 
$msgs = imap_fetch_overview($conn, '1:5'); /** first 5 messages */ 
foreach ($msgs as $msg) { 
    $source = imap_fetchheader($conn, $msg->msgno) . imap_body($conn, $msg->msgno); 
    print $source; 
} 
0

Một sai lầm phổ biến là sử dụng "\n" hoặc PHP_EOL.

Theo RFC RFC821, RFC2060, RFC1939 "\r\n" nên được sử dụng. Trong khi một số máy chủ tự động chuyển đổi những lỗi đó, Cyrus không và ném một lỗi hay.

PHP_EOL là hệ thống tùy thuộc vào hằng số, ví dụ: "\n" trên Linux, "\r" trên máy Mac và "\r\n" trên Windows.

Hơn nữa imap_fetchheader() chứa dấu sau "\r\n" như mong đợi. Vì vậy, ví dụ chính xác sẽ là:

$source = imap_fetchheader($conn, $msg->msgno) . imap_body($conn, $msg->msgno); 
12

Tôi đã xem qua câu hỏi này khi tôi đang tìm kiếm cùng một vấn đề. Tôi biết nó phải dễ hơn giải pháp của hakre và tôi tìm thấy câu trả lời đúng trên trang cho imap_fetchbody trên một số post from 5 years ago.

Để nhận được thông báo liệu đầy đủ chỉ cần sử dụng như sau:

$imap_stream = imap_open($server, $username, $password); 
$raw_full_email = imap_fetchbody($imap_stream, $msg_num, ""); 

Thông báo chuỗi rỗng như tham số thứ ba của imap_fetchbody này nghĩa tất cả các bộ phận và phụ phần của thư điện tử, bao gồm tiêu đề và tất cả các cơ quan.

+0

Tuyệt vời! Nó có tìm nạp tệp đính kèm không? – VeeeneX

+2

@VeeeneX Có, nó tải mọi thứ. Các tập tin đính kèm cần phải được giải mã chúng thường được mã hóa base64. Ngày nay, các nhà cung cấp dịch vụ email cho phép gửi "tệp đính kèm" bằng OneDrive/GoogleDrive, đây không phải là tệp đính kèm thực sự, chúng sẽ không được tìm nạp. –

+0

Đây là giải pháp tốt nhất - chỉ có một dòng để truy xuất thư hoàn chỉnh để bạn có thể đưa nó vào một trình phân tích cú pháp. $ raw_full_email = imap_fetchbody ($ handle, $ num, ""); $ Parser = PhpMimeMailParser \ Parser() mới; $ Parser-> setText ($ raw_full_email); – Tramov

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