承前一章,我要如何用程式發信呢,首先我們要了解,一封合格的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);
}
,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);
}