2013-03-21 191 views
11

我有通過base64編碼和8位編碼發送的電子郵件。我想知道如何使用imap_fetchstructure檢查郵件的編碼(已經這樣做了大約兩個小時,所以丟失了),然後正確解碼。PHP IMAP解碼消息

Gmail和郵箱(iOS上的應用程序)將它作爲8位發送,而Windows 8的郵件應用程序將其作爲base64發送。無論哪種方式,我需要通過檢測它使用的編碼類型來解碼其8位或base64。

使用PHP 5.1.6(是的,我應該更新,一直很忙)。

我真的沒有代碼顯示。這是我擁有的:

<?php 
$hostname = '{********:993/imap/ssl}INBOX'; 
$username = '*********'; 
$password = '******'; 

$inbox = imap_open($hostname,$username,$password) or die('Cannot connect to server: ' . imap_last_error()); 

$emails = imap_search($inbox,'ALL'); 

if($emails) { 

    $output = ''; 

    rsort($emails); 

    foreach($emails as $email_number) { 

     $overview = imap_fetch_overview($inbox,$email_number,0); 
     $message = imap_fetchbody($inbox,$email_number,2); 
     $struct = imap_fetchstructure($inbox, $email_number); 

     $output.= '<div class="toggle'.($overview[0]->seen ? 'read' : 'unread').'">'; 
     $output.= '<span class="subject">'.$overview[0]->subject.'</span> '; 
     $output.= '<span class="from">'.$overview[0]->from.'</span>'; 
     $output.= '<span class="date">on '.$overview[0]->date.'</span>'; 
     $output.= '</div>'; 

     /* output the email body */ 
     $output.= '<div class="body">'.$message.'</div>'; 
    } 

    echo $output; 
} 

imap_close($inbox); 
?> 
+0

是字符不來正確地爲你的電子郵件? – 2013-03-21 05:07:45

+0

@DeadMan來自Windows Mail的電子郵件(Win8中的Metro應用程序)是base64,而來自其他應用程序的則是8位。 – alexpja 2013-03-21 05:10:29

+0

['imap_fetchstructure()'](http://php.net/manual/en/function.imap-fetchstructure.php)的結果應該有'encoding'屬性。這不適合你? – Phil 2013-03-27 03:55:49

回答

33

imap_bodystruct()或imap_fetchstructure()應該將此信息返回給您。下面的代碼應該做的正是你要尋找的:對於imap_fetchstructure)

<?php 
$hostname = '{********:993/imap/ssl}INBOX'; 
$username = '*********'; 
$password = '******'; 

$inbox = imap_open($hostname,$username,$password) or die('Cannot connect to server: ' . imap_last_error()); 

$emails = imap_search($inbox,'ALL'); 

if($emails) { 
    $output = ''; 
    rsort($emails); 

    foreach($emails as $email_number) { 
     $overview = imap_fetch_overview($inbox,$email_number,0); 
     $structure = imap_fetchstructure($inbox, $email_number); 

     if(isset($structure->parts) && is_array($structure->parts) && isset($structure->parts[1])) { 
      $part = $structure->parts[1]; 
      $message = imap_fetchbody($inbox,$email_number,2); 

      if($part->encoding == 3) { 
       $message = imap_base64($message); 
      } else if($part->encoding == 1) { 
       $message = imap_8bit($message); 
      } else { 
       $message = imap_qprint($message); 
      } 
     } 

     $output.= '<div class="toggle'.($overview[0]->seen ? 'read' : 'unread').'">'; 
     $output.= '<span class="from">From: '.utf8_decode(imap_utf8($overview[0]->from)).'</span>'; 
     $output.= '<span class="date">on '.utf8_decode(imap_utf8($overview[0]->date)).'</span>'; 
     $output.= '<br /><span class="subject">Subject('.$part->encoding.'): '.utf8_decode(imap_utf8($overview[0]->subject)).'</span> '; 
     $output.= '</div>'; 

     $output.= '<div class="body">'.$message.'</div><hr />'; 
    } 

    echo $output; 
} 

imap_close($inbox); 
?> 
+0

它已經解碼了大部分消息,除了Windows 8上的Windows Mail之外。希望沒有人使用它。謝謝! – alexpja 2013-04-02 20:10:01

+0

你能否檢查[this](http://stackoverflow.com/questions/39745784/how-to-fetch-to-and-cc-email-using-imap-php)需要幫助 – 2016-09-28 11:19:37

+0

爲什麼要分流4個可能的6編碼到else塊處理quoted_printables? http://php.net/manual/en/function.imap-fetchstructure.php – Andrew 2017-09-15 13:07:52

1

返回的對象(

  1. 編碼(身體傳輸編碼)

傳輸編碼(可能有變化使用庫)

0 7BIT 1 8BIT 2 BINARY 3 BASE64 4引用可打印 5其他

$s = imap_fetchstructure($mbox,$mid); 
if ($s->encoding==3) 
    $data = base64_decode($data); 
5

你可以看看下面這個例子。

Imap/Imap

這裏的代碼片段

switch ($encoding) { 
    # 7BIT 
    case 0: 
     return $text; 
    # 8BIT 
    case 1: 
     return quoted_printable_decode(imap_8bit($text)); 
    # BINARY 
    case 2: 
     return imap_binary($text); 
    # BASE64 
    case 3: 
     return imap_base64($text); 
    # QUOTED-PRINTABLE 
    case 4: 
     return quoted_printable_decode($text); 
    # OTHER 
    case 5: 
     return $text; 
    # UNKNOWN 
    default: 
     return $text; 
} 
+0

我必須在ENC7BIT消息上使用'imap_qprint'才能正確顯示。 您可以使用[PHP常數](http://php.net/manual/en/function.imap-fetchstructure.php#refsect1-function.imap-fetchstructure-returnvalues)代替數字: 'case ENC7BIT:' – Genjo 2016-08-08 12:39:15