DeCoding.php
2.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<?php
namespace Lib\Mail;
/**
 * 解码邮件内容
 * @author:dc
 * @time 2022/8/12 9:33
 * Class DeCoding
 * @package App\Mail\lib\MailParse
 */
class DeCoding {
    /**
     * @param $sText
     * @param bool $bEmulate_imap_8bit
     * @return string
     * @author:dc
     * @time 2022/8/12 9:34
     */
    public static function de8bit($sText,$bEmulate_imap_8bit=true) {
        // split text into lines
        $aLines=explode(chr(13).chr(10),$sText);
        for ($i=0;$i<count($aLines);$i++) {
            $sLine =& $aLines[$i];
            if (strlen($sLine)===0) continue; // do nothing, if empty
            $sRegExp = '/[^\x09\x20\x21-\x3C\x3E-\x7E]/e';
            // imap_8bit encodes x09 everywhere, not only at lineends,
            // for EBCDIC safeness encode !"#$@[\]^`{|}~,
            // for complete safeness encode every character :)
            if ($bEmulate_imap_8bit)
                $sRegExp = '/[^\x20\x21-\x3C\x3E-\x7E]/e';
            $sReplmt = 'sprintf( "=%02X", ord ( "$0" ) ) ;';
            $sLine = preg_replace( $sRegExp, $sReplmt, $sLine );
            // encode x09,x20 at lineends
            {
                $iLength = strlen($sLine);
                $iLastChar = ord($sLine[$iLength-1]);
                //              !!!!!!!!
                // imap_8_bit does not encode x20 at the very end of a text,
                // here is, where I don't agree with imap_8_bit,
                // please correct me, if I'm wrong,
                // or comment next line for RFC2045 conformance, if you like
                if (!($bEmulate_imap_8bit && ($i==count($aLines)-1)))
                    if (($iLastChar==0x09)||($iLastChar==0x20)) {
                        $sLine{$iLength-1}='=';
                        $sLine .= ($iLastChar==0x09)?'09':'20';
                    }
            }    // imap_8bit encodes x20 before chr(13), too
            // although IMHO not requested by RFC2045, why not do it safer :)
            // and why not encode any x20 around chr(10) or chr(13)
            if ($bEmulate_imap_8bit) {
                $sLine=str_replace(' =0D','=20=0D',$sLine);
                //$sLine=str_replace(' =0A','=20=0A',$sLine);
                //$sLine=str_replace('=0D ','=0D=20',$sLine);
                //$sLine=str_replace('=0A ','=0A=20',$sLine);
            }
            // finally split into softlines no longer than 76 chars,
            // for even more safeness one could encode x09,x20
            // at the very first character of the line
            // and after soft linebreaks, as well,
            // but this wouldn't be caught by such an easy RegExp
            preg_match_all( '/.{1,73}([^=]{0,2})?/', $sLine, $aMatch );
            $sLine = implode( '=' . chr(13).chr(10), $aMatch[0] ); // add soft crlf's
        }
        // join lines into text
        return implode(chr(13).chr(10),$aLines);
    }
}