2011-12-24 11 views
7

Sto provando a reindirizzare i miei messaggi in arrivo a uno script PHP in modo da poterli archiviare in un database e altre cose. Sto usando la classe MIME E-mail message parser (registration required) anche se non penso sia importante.Modo corretto per decodificare l'oggetto della posta in arrivo (utf 8)

Ho un problema con le e-mail. Funziona benissimo quando il titolo è in inglese, ma se il soggetto utilizza caratteri non latini ottengo qualcosa come

=?UTF-8?B?2KLYstmF2KfbjNi0?= 

per un titolo come یک دو سه

decodifico l'argomento in questo modo:

Funziona bene con soggetti brevi con 10-15 caratteri simili ma con un titolo più lungo ottengo metà del titolo originale con qualcosa come alla fine.

Se il titolo è ancora più lungo, come 30 caratteri, non ottengo nulla. Lo sto facendo bene?

+1

Questo non è il software di qualità più elevata che hai scelto lì. Controlla http://stackoverflow.com/questions/4721410/best-way-to-handle-email-parsing-decoding-in-php, probabilmente tutti eseguono la decodifica e non richiedono tali hack di ricezione. – mario

risposta

12

Nonostante abbia quasi un anno di età, ho trovato questo e sto affrontando un problema simile.

Non sono sicuro del motivo per cui stai ricevendo caratteri strani, ma forse stai cercando di visualizzarli da qualche parte il tuo set di caratteri non è supportato.

Ecco un codice che ho scritto che dovrebbe gestire tutto tranne la conversione di charset, che è un grosso problema che molte librerie gestiscono molto meglio. (PHP di MB library, per esempio)

class mail { 
    /** 
     * If you change one of these, please check the other for fixes as well 
    * 
    * @const Pattern to match RFC 2047 charset encodings in mail headers 
    */ 
    const rfc2047header = '/=\?([^ ?]+)\?([BQbq])\?([^ ?]+)\?=/'; 

    const rfc2047header_spaces = '/(=\?[^ ?]+\?[BQbq]\?[^ ?]+\?=)\s+(=\?[^ ?]+\?[BQbq]\?[^ ?]+\?=)/'; 

    /** 
    * http://www.rfc-archive.org/getrfc.php?rfc=2047 
    * 
    * =?<charset>?<encoding>?<data>?= 
    * 
    * @param string $header 
    */ 
    public static function is_encoded_header($header) { 
     // e.g. =?utf-8?q?Re=3a=20Support=3a=204D09EE9A=20=2d=20Re=3a=20Support=3a=204D078032=20=2d=20Wordpress=20Plugin?= 
     // e.g. =?utf-8?q?Wordpress=20Plugin?= 
     return preg_match(self::rfc2047header, $header) !== 0; 
    } 

    public static function header_charsets($header) { 
     $matches = null; 
     if (!preg_match_all(self::rfc2047header, $header, $matches, PREG_PATTERN_ORDER)) { 
      return array(); 
     } 
     return array_map('strtoupper', $matches[1]); 
    } 

    public static function decode_header($header) { 
     $matches = null; 

     /* Repair instances where two encodings are together and separated by a space (strip the spaces) */ 
     $header = preg_replace(self::rfc2047header_spaces, "$1$2", $header); 

     /* Now see if any encodings exist and match them */ 
     if (!preg_match_all(self::rfc2047header, $header, $matches, PREG_SET_ORDER)) { 
      return $header; 
     } 
     foreach ($matches as $header_match) { 
      list($match, $charset, $encoding, $data) = $header_match; 
      $encoding = strtoupper($encoding); 
      switch ($encoding) { 
       case 'B': 
        $data = base64_decode($data); 
        break; 
       case 'Q': 
        $data = quoted_printable_decode(str_replace("_", " ", $data)); 
        break; 
       default: 
        throw new Exception("preg_match_all is busted: didn't find B or Q in encoding $header"); 
      } 
      // This part needs to handle every charset 
      switch (strtoupper($charset)) { 
       case "UTF-8": 
        break; 
       default: 
        /* Here's where you should handle other character sets! */ 
        throw new Exception("Unknown charset in header - time to write some code."); 
      } 
      $header = str_replace($match, $data, $header); 
     } 
     return $header; 
    } 
} 

Quando viene eseguito tramite uno script e visualizzato in un browser usando UTF-8, il risultato è:

آزمایش

si farebbe funzionare in questo modo:

$decoded = mail::decode_header("=?UTF-8?B?2KLYstmF2KfbjNi0?="); 
+0

Puoi usare '$ data = iconv ($ charset, 'UTF-8 // TRANSLIT', $ data);' o '$ data = mb_convert_encoding ($ data, 'UTF-8', $ charset);' per decodifica di caratteri insoliti.Preferisco la seconda strada. – Stalinko

+0

grazie .. @razzed – NaveenDA

2

Utilizzare la funzione php:

<?php 
imap_utf8($text); 
?> 
2

utilizzare PHP funzione nativa

<?php 
mb_decode_mimeheader($text); 
?> 

Questa funzione può gestire utf8 così come stringa iso-8859-1. L'ho provato.

+0

Questo decodificherà anche i soggetti non utf8. Prova se (preg_match ('/ \? Utf-8 \? /', $ Subject)) $ subject = mb_decode_mimeheader ($ subject); – Juergen

Problemi correlati