2013-03-21 2 views
11

У меня есть сообщения, отправленные через кодировку base64 и 8-битную кодировку. Мне было интересно, как я могу проверить кодировку сообщения с помощью imap_fetchstructure (делал это примерно два часа, поэтому потерял), а затем правильно декодировал его.PHP IMAP-сообщения декодирования

Gmail и почтовый ящик (приложение на iOS) отправляют его как 8 бит, в то время как приложение Mail 8 от Microsoft отправляет его как 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

ли персонажи не приходя правильно для вас в электронной почте? –

+0

@DeadMan Письма из Windows Mail (приложение Metro в Win8) - base64, а те, которые поступают из других приложений, - 8 бит. – alexpja

+0

Результат ['imap_fetchstructure()'] (http://php.net/manual/en/function.imap-fetchstructure.php) должен иметь свойство 'encoding'. Это не работает для вас? – Phil

ответ

33

imap_bodystruct() или 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 Mail на Windows 8. Надеюсь, никто этого не использует. Спасибо! – alexpja

+0

Можете ли вы проверить [это] (http://stackoverflow.com/questions/39745784/how-to-fetch-to-and-cc-email-using-imap-php) нужна помощь –

+0

Почему шунт 4 из возможных 6 кодирования в обработку блока else в quoted_printables? http://php.net/manual/en/function.imap-fetchstructure.php – Andrew

1

возвращаемых объекты для imap_fetchstructure()

  1. кодирования (Body кодирования передачи)

Передача кодировки (может изменяться в зависимости от используемая библиотека)

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

Мне нужно было использовать 'imap_qprint' в сообщениях ENC7BIT для корректного отображения. Вы можете использовать [PHP-константы] (http://php.net/manual/en/function.imap-fetchstructure.php#refsect1-function.imap-fetchstructure-returnvalues) вместо чисел: 'case ENC7BIT:' – Genjo

Смежные вопросы