Email介紹(二)

承前一章,我要如何用程式發信呢,首先我們要了解,一封合格的email主要分成兩個部分

,Header以及body。

Header主要描述這封email是來自哪裡,要傳送給誰,主旨是什麼,什麼時間寄出來的信,使用

什麼編碼等等…;而body就是這封信的內容,包含文字內容還有附檔等…。

如果你的信件有好幾個部分(內文、好幾個附檔…),那就用一個unique id把每個部份隔開

Header大概像下面這樣


X-Priority: 3
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
Content-type: text/html;charset=utf-8
Content-type: multipart/mixed; boundary="$id"; charset="UTF-8"
From: $from
Subject: $title
To: $to

因為mail box同一個人的信件其實會寫成一個很大的檔案,因此他需要判斷每一個信的開頭

與結尾,所以需要一個unique的ID,同時利用這個ID區分整個內容的Header以及Body有幾

個部分,在header會先宣告這個ID,下面每一個部分開頭就是–$id,結束的時候就是–$id–,

這封信就結束了,如果你的email有多個部分,則需要加上multipart/mixed

Body的部分則是長得像下面這樣


--$id
Content-type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 8bit

內容

每一塊body前面還是要宣告他是什麼類型的內容,什麼編碼,是否經過MIME過(附件),宣告

完之後空兩行在接內容,像上面這就是文字的部分,如果還有夾檔則是在加一塊


--$id
Content-type: application/unknown;name=$filename
Content-transfer-encoding: base64
Content-disposition: attachment; filename=$filename

編碼後的檔案

像上面就是宣告用base64編碼,最後再用一個–$id–結束就可以了

以PHP的範例來說就像下面這樣


        function mailto($from,$to,$subject,$msg,$filename='')
  {
    $mailto = '';
    if(count($to) > 1)
      for($i = 0;$i < count($to);$i++)
        $mailto .= "$to[$i],";
    else
      $mailto = $to;
    $boundary = uniqid(""); // 產生分隔字串 
    $subject = '=?utf-8?B?'.base64_encode("$subject").'?='; // 標題加密(防亂碼) 
    $headers = ''; 
    $headers .= "MIME-Version: 1.0\r\n"; 
    $headers .= "Content-type: multipart/mixed; boundary=\"$boundary\"; charset=\"UTF-8\"\r\n"; //宣告分隔字串 
    $headers .= 'From:'.$from."\r\n"; // 設定寄件者 
    $headers .= "X-Mailer: PHP/".phpversion()."\r\n"; 
    $body .= "--$boundary\r\n"; 
    $body .= "Content-type: text/plain; charset=\"UTF-8\"\r\n";// 信件本文header 
    $body .= "Content-Transfer-Encoding: 8bit\r\n\r\n";// 信件本文header 
    $body .= $msg."\r\n"; // 本文內容 
    //附加檔案處理
    if(!is_array($filename))
      $files[0] = $filename;
    if( count($files) != 0)
    {   
      for($i = 0;$i < count($files);$i++)
      { 
        $mimeType = mime_content_type($files[$i]); // 判斷檔案類型 ,php.ini要開啟php_mime_magic.dll
        if(!$mimeType)
          $mimeType = "application/unknown"; // 若判斷不出則設為未知 
        $data = chunk_split(base64_encode(file_get_contents($files[$i])));
        $file = basename($files[$i]); //傳回不包含路徑的檔案名稱(mail中會顯示的檔名)
        $body .= "--$boundary\r\n"; 
        $body .= "Content-type: $mimeType; name=$file\r\n"; 
        $body .= "Content-transfer-encoding: base64\r\n"; 
        $body .= "Content-disposition: attachment; filename=$file\r\n\r\n"; 
        $body .= "$data\r\n"; 
      }
    }
    $body .= "--$boundary--";//郵件結尾
    mail($mailto, $subject, $body, $headers); // 寄出信件
  }

perl範例


sub mailto
{
    my ($from,$to,$title,$content,$file) = @_;
    my $id = '';
    for(my $i = 0;$i <= 20;$i++){$id .= chr(97 + int(rand(26)));}
    $title = '=?utf-8?B?'.substr(encode_base64($title),0,-1).'?=';
    my $header = "X-Priority: 3\r\nMIME-Version: 1.0\r\nContent-Transfer-Encoding: 8bit\r\nContent-type: text/html;charset=utf-8
Content-type: multipart/mixed; boundary=\"$id\"; charset=\"UTF-8\"\r\nFrom: $from\r\nSubject: $title\r\nTo: $to\r\n--$id
Content-type: text/plain; charset=\"UTF-8\"\r\nContent-Transfer-Encoding: 8bit\r\n\r\n";
    #夾檔
    if($file ne ''){
        my $filename = basename($file);
        my $data = encode_base64(`cat $filename`);
        $content .= "\r\n\r\n--$id\r\nContent-type: application/unknown;name=$filename\r\nContent-transfer-encoding: base64
Content-disposition: attachment; filename=$filename\r\n\r\n$data";
    }
    $content .= "--$id--";
    open(MM,"|/usr/lib/sendmail -oem -oi -f '$from' -t '$to'");
    print MM "$header$content";
    close(MM);
}