直播中
核心:方法
我們將MIME信息頭的生成,MIME段頭的生成和最終的郵件消息的生成分成幾個(gè)模塊。方法的實(shí)現(xiàn)是直接從我們前面遇到的MIME基礎(chǔ)而來(lái)的。
<?php
function attach($data, $description = "", $contenttype = OCTET, $encoding = BASE64, $disp = '') {
if (empty($data))
return 0;
if (trim($contenttype) == '')
$contenttype = OCTET ;
if (trim($encoding) == '')
$encoding = BASE64;
if ($encoding == BIT7)
$emsg = $data;
elseif ($encoding == QP)
$emsg = $$this->qp_func($data);
elseif ($encoding == BASE64) {
if (!$this->base64_func) # 檢查是否有用戶自動(dòng)定函數(shù)
$emsg = base64_encode($data);
else
$emsg = $$this->base64_func($data);
}
$emsg = chunk_split($emsg);
//檢查是否content-type是text/plain并且如果沒(méi)有指定charset,追加缺省的CHARSET
if (preg_match("!^".TEXT."!i", $contenttype) && !preg_match("!;charset=!i", $contenttype))
$contenttype .= ";\r\n\tcharset=".CHARSET ;
$msg = sprintf("Content-Type: %sContent-Transfer-Encoding: %s%s%s%s",
$contenttype.CRLF,
$encoding.CRLF,
((($description) && (BODY != $description))?"Content-Description: $description".CRLF:""),
($disp?"Content-Disposition: $disp".CRLF:""),
CRLF.$emsg.CRLF);
BODY==$description? $this->mimeparts[0] = $msg: $this->mimeparts[] = $msg ;
return sizeof($this->mimeparts);
}
?>
讓我們仔細(xì)地看一下這個(gè)方法(對(duì)于其它的大部分方法也將如此):
這個(gè)方法使用的參數(shù)有:
所附的實(shí)際數(shù)據(jù)($data)
與Content-Description頭相應(yīng)的數(shù)據(jù)描述($description)
將用在Content-Type頭中的數(shù)據(jù)content-type值($contentype)
用在Content-Transfer-Encoding中的編碼值($encoding)
用在Content-Disposition頭$disp中的布局值,可以是INLINE或ATTACH,兩個(gè)都是常量
如BASE64,TEXT這樣的值等等,作為常量被定義在附加的.def文件中。
使用$encoding值來(lái)決定需要用哪種編碼方式對(duì)數(shù)據(jù)進(jìn)行編碼。有效的值是BIT7(或7bit),QP或BASE64。
這個(gè)函數(shù)同時(shí)也檢查了是否用戶要使用他/她自已的BASE64或QP函數(shù)。在寫(xiě)這篇文章時(shí),在我們的類中
只有BIT7和BASE64被實(shí)現(xiàn)了,然而,你可以傳遞你自已的quoted-printable 函數(shù)來(lái)使用,通過(guò)在前面
討論的$qp_func類變量。
在編碼處理之后,你會(huì)注意到對(duì)編碼的信息使用了chunk_split()。這個(gè)函數(shù)根據(jù)可選長(zhǎng)度將字符串分
割成小段。因?yàn)槲覀儧](méi)有指出長(zhǎng)度,缺省長(zhǎng)度使用76。這個(gè)非常附合郵件處理的習(xí)慣。
接著,如果$contenttype參數(shù)包含text/plain,則必須給出"charset=" 參數(shù)的值。它的缺省值被定義
在常量CHARSET中,值為us-ascii。注意當(dāng)頭使用參數(shù)值傳遞時(shí),在頭與參數(shù)之間必須有一個(gè)分號(hào)(;)。
例如,Content-Type: text/plain; charset=us-ascii
如果其它MIME段頭各自的值被傳遞給這個(gè)方法,這些段頭被創(chuàng)建。畢竟我們不想擁有一個(gè)沒(méi)有描述的
Content-Description頭。在創(chuàng)建這些頭之后,我們追加上經(jīng)過(guò)編碼的數(shù)據(jù)部分信息。(檢查一下方法
中的sprintf()語(yǔ)句)。
同樣,注意我們使用了一個(gè)叫BODY(又是一個(gè)常量)的特別描述字段。這就是我們用在類實(shí)現(xiàn)中的東西。
如果描述字段與BODY一樣,我們將其賦給$mimeheaders數(shù)組中的第一個(gè)元素。對(duì)于這個(gè)請(qǐng)多讀幾遍。
attach() 返回$mimeparts數(shù)組的當(dāng)前大小,用在調(diào)用腳本的引用中。通過(guò)這種方法就可以知道一個(gè)附
件"X"存在哪一個(gè)索引中(實(shí)際返回的值要比在數(shù)組中的索引小1)
注意所有的頭必須用一個(gè)CRLF(\r\n)序列結(jié)束。
接著,我們看一下fattach()方法,fattach()與attach()相似,但是它使用一個(gè)文件名作為它的第一個(gè)
參數(shù)(作為attach()中$data的替換)。這個(gè)方法只是一個(gè)封裝,以便調(diào)用者可以用一個(gè)文件來(lái)調(diào)用fattach。
fattach()然后將文件讀出,接著調(diào)用attach()來(lái)追加數(shù)據(jù)。這個(gè)方法在失敗時(shí)返回0,可以在$errstr 變量
中找到解釋或者當(dāng)成功時(shí),返回文件附件在$mimeparts數(shù)組中的索引號(hào)。
我們現(xiàn)在已經(jīng)開(kāi)發(fā)了附加數(shù)據(jù)的功能,對(duì)它們進(jìn)行編碼并且將單獨(dú)的MIME段放在私有數(shù)組中。還需要完
成的工作是:
完成MIME的各個(gè)段
創(chuàng)建包含MIME信息頭的郵件信息頭,郵件原始的信息頭(如To:, From:等等)并且包括任何用戶定義
的頭。
在頭后面追加完整的MIME段,這樣一個(gè)完整的郵件包就生成了。