【问题标题】:How to really decode a 7Bit email message using PHP?如何使用 PHP 真正解码 7 位电子邮件消息?
【发布时间】:2015-04-29 19:26:20
【问题描述】:

我的代码可以从服务器读取电子邮件,然后在将数据插入数据库之前对其进行解析。

我在 PHP 中使用 IMAP extension 来帮助我解决这个问题。

这是我正在做的读取数据

//read new messages
private function _getNewMessages(){

    // Checks the inbox
    if ($messages = imap_search($this->conn,'ALL'))
    {
        // Sorts the messages newest first
        sort($messages);

        // Loops through the messages
        foreach ($messages as $id)
        {
            // Grabs the overview and body
            //$overview = imap_fetch_overview($this->conn, $id, 0);
            $struct = imap_fetchstructure($this->conn, $id, 0);
            $header = imap_headerinfo($this->conn, $id);
            $message = imap_fetchbody($this->conn, $id, 1);

            //decode the message
            if(isset($struct->encoding)){
                $message = $this->_decodeMessage($message, $struct->encoding);
            }


            $from = $header->from[0]->mailbox . '@' . $header->from[0]->host;
            $subject = $header->subject;    
            echo  $message;
        }
    }
    else
    {
        exit('No messages to process');
    }
}

我看到的问题是,当消息以值 0“7 位”编码时,它返回黑色。似乎解码无法正确解码消息。

我正在使用这个函数来解码 7 位

    // function to decode 7BIT encoded message
    private function _decode7Bit($text) {
        // If there are no spaces on the first line, assume that the body is
        // actually base64-encoded, and decode it.
        $lines = explode("\r\n", $text);
        $first_line_words = explode(' ', $lines[0]);
        if ($first_line_words[0] == $lines[0]) {
            $text = base64_decode($text);
        }

        // Manually convert common encoded characters into their UTF-8 equivalents.
        $characters = array(
                     '=20' => ' ', // space.
                     '=E2=80=99' => "'", // single quote.
                     '=0A' => "\r\n", // line break.
                     '=A0' => ' ', // non-breaking space.
                     '=C2=A0' => ' ', // non-breaking space.
                     "=\r\n" => '', // joined line.
                     '=E2=80=A6' => '…', // ellipsis.
                     '=E2=80=A2' => '•', // bullet.
        );

        // Loop through the encoded characters and replace any that are found.
        foreach ($characters as $key => $value) {
            $text = str_replace($key, $value, $text);
        }

        return $text;
    }

我也试过这种方法来解码消息

/**
 * decoding 7bit strings to ASCII
 * @param string $text
 * @return string
 */
function decode7bit($text){
        $ret = '';
        $data = str_split(pack('H*', $text));

        $mask = 0xFF;
        $shift = 0;
        $carry = 0;
        foreach ($data as $char) {
                if ($shift == 7) {
                        $ret .= chr($carry);
                        $carry = 0;
                        $shift = 0;
                }

                $a      =       ($mask >> ($shift+1)) & 0xFF;
                $b      =       $a ^ 0xFF;

                $digit = ($carry) | ((ord($char) & $a) << ($shift)) & 0xFF;
                $carry = (ord($char) & $b) >> (7-$shift);
                $ret .= chr($digit);

                $shift++;
        }
        if ($carry) $ret .= chr($carry);
        return $ret;
}

但消息是空白的。

我在这里做错了什么?我可以做些什么来确保消息被正确解码?

谢谢

【问题讨论】:

  • 试过imap_utf7_decode?
  • 我刚刚做了,解码后仍然是一条黑消息
  • base-64 解码后的$str = mb_convert_encoding($str, "UTF-7", "UTF-8"); 怎么样(如果适用)
  • @drew010 我试过这个,但没有奏效。检查base64decoding是否适用我使用了这个方法private function _isEncodedBase64($date){ if ( base64_encode(base64_decode($data)) === $data){ return true; } return false; }
  • “解码后的黑消息”是什么意思?能否提供详细信息?

标签: php email base64 imap 7-bit


【解决方案1】:

根据您描述的字符编码,您的文本似乎是使用带引号的 printable 编码的。

尝试使用解码:

echo quoted_printable_decode($text);

【讨论】:

    【解决方案2】:

    我发现了这个问题。我检查消息是否是 base64 编码的方式并不好。所以我把我的功能改成这个

    private function _isEncodedBase64($date){
    
            if ( base64_encode(base64_decode($data)) === $data){
                return true;
            }
    
            return false;
        }
    
        // function to decode 7BIT encoded message
        private function _decode7Bit($text) {
            // If there are no spaces on the first line, assume that the body is
            // actually base64-encoded, and decode it.      
            if($this->_isEncodedBase64($text)){
                $text = base64_decode($text);
            } 
    
    
            // Manually convert common encoded characters into their UTF-8 equivalents.
            $characters = array(
                         '=20' => ' ', // space.
                         '=E2=80=99' => "'", // single quote.
                         '=0A' => "\r\n", // line break.
                         '=A0' => ' ', // non-breaking space.
                         '=C2=A0' => ' ', // non-breaking space.
                         "=\r\n" => '', // joined line.
                         '=E2=80=A6' => '…', // ellipsis.
                         '=E2=80=A2' => '•', // bullet.
            );
    
            // Loop through the encoded characters and replace any that are found.
            foreach ($characters as $key => $value) {
                $text = str_replace($key, $value, $text);
            }
            return $text;
        }
    

    【讨论】:

    • 这里有 Content-Printable-Decoding 的代码,我敢肯定它在 PHP 中有一个解码器。
    【解决方案3】:

    不需要的代码。只需在 php 中使用quoted_printable_decode 即可。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-09
      • 1970-01-01
      • 2014-05-15
      • 2020-04-29
      • 1970-01-01
      • 2021-02-06
      • 2020-12-23
      • 2011-06-04
      相关资源
      最近更新 更多