直播中
我們將考查的下一個(gè)方法是,build_message(),它占據(jù)了整個(gè)工作的大部分,但它是通過(guò)一個(gè)
gen_email()的方法來(lái)調(diào)用的。請(qǐng)注意build_message()是一個(gè)私有方法。
<?php
function build_message() {
$msg = "";
$boundary = 'PM'.chr(rand(65, 91)).'------'.md5(uniqid(rand())); # 邊界標(biāo)識(shí)
$nparts = sizeof($this->mimeparts);
//情況1:存在附件列表,所以MIME信息頭必須是multipart/mixed
if (is_array($this->mimeparts) && ($nparts > 1)) {
$c_ver = "MIME-Version: 1.0".CRLF;
$c_type = 'Content-Type: multipart/mixed;'.CRLF."\tboundary=\"$boundary\"".CRLF;
$c_enc = "Content-Transfer-Encoding: ".BIT7.CRLF;
$c_desc = $c_desc?"Content-Description: $c_desc".CRLF:"";
$warning = CRLF.WARNING.CRLF.CRLF ;
// 如果存在MIMIE段,則郵件體也要變成附件
if (!empty($this->body)) {
$this->attach($this->body, BODY, TEXT, BIT7);
}
// 現(xiàn)在創(chuàng)建郵件的各個(gè)MIME段
for ($i=0 ; $i < $nparts; $i++) {
if (!empty($this->mimeparts[$i]))
$msg .= CRLF.'--'.$boundary.CRLF.$this->mimeparts[$i].CRLF;
}
$msg .= '--'.$boundary.'--'.CRLF;
$msg = $c_ver.$c_type.$c_enc.$c_desc.$warning.$msg;
} else {
if (!empty($this->body)) $msg .= $this->body.CRLF.CRLF;
}
return $msg;
}
?>
這個(gè)方法有點(diǎn)自相予盾,簡(jiǎn)單而又復(fù)雜。要看你自已怎么看了。
我們?cè)谇懊孀x到(在MIME基礎(chǔ)中),每一個(gè)MIME段都有一個(gè)邊界標(biāo)記,這個(gè)標(biāo)記有一個(gè)唯一的id。邊
界標(biāo)記被用在:
MIME信息頭中,用來(lái)指示附件必須從哪進(jìn)行劃分
MIME段中;實(shí)際用在每一段的前面和后面來(lái)劃分附件的邊界。(回想一下Alexander的有著圖片
和圖譜的郵件?。?
(記?。鹤詈笠粋€(gè)邊界標(biāo)記要以兩個(gè)連接符(--)結(jié)束,用于指示范圍結(jié)束)。
$boundary包含了邊界標(biāo)記,并且它是通過(guò)一個(gè)隨機(jī)數(shù)進(jìn)行了唯一化再做MD5哈希生成的。另外,我們
給$boundary冠以一個(gè)"PM?"的前綴,這里"?"是一個(gè)隨機(jī)字母。舉一個(gè)$boundary的例子就是
"PMK------2345ee5de0052eba4daf47287953d37e"(PM表示PHP MIME,所以你可以將其改為你的可能的
初始值?。?
在生成MIME頭的處理中我們必須考慮兩種情況。這些情況影響了郵件的原始郵件體($body在構(gòu)造函數(shù)
中)以哪種方式被看待和MIME信息頭的特別表示。情況1就是寫這篇文章的原因,并且你會(huì)看到:可以
有許多的附件被包含!在這種情況下,請(qǐng)注意作為信息的部分被放上了警告字符串"This is a MIME
encoding message"。因此,真正的消息體本身也必須以附件形式加到信息中!郵件的文本通常是附件
列表中的第一個(gè)附件,在我們的例子中就是$mimeparts。這個(gè)正好就是為什么我們要占用一個(gè)
$mimeparts索引的原因,以便讓第一個(gè)索引(是0)可以用于郵件文本部分。郵件體必須以7bit編碼進(jìn)
行附加。
<?php
if (!empty($this->body)) {
$this->attach($this->body, BODY, TEXT, BIT7);
}
?>
上面的一小段代碼完成附加郵件文本部分作為一個(gè)MIME附件的工作。注意,我們使用了'BODY'常量來(lái)
指示attach()要將附件加到何處。
第二種情況就是當(dāng)不存在附件時(shí),在這種情況下,如果提供了郵件文本,它將是包含在局部變量$msg
中的唯一信息;在這種情況下不需要MIME頭。(然而,在這種情況下我們還應(yīng)該只把MIME-Version頭
指定出來(lái)----回過(guò)頭到再看一下前面的演示的最簡(jiǎn)單的MIME信息。)
MIME信息頭(MIME-Version,Content-Type, 等等。)在有附件的時(shí)候被創(chuàng)建。為了用MIME消息頭來(lái)
創(chuàng)建消息體,首先MIME信息頭要被創(chuàng)建。然后各個(gè)有效的MIME段通過(guò)$mimeheaders數(shù)組被反復(fù)處理。
這就是邊界標(biāo)識(shí)被實(shí)際使用的地點(diǎn)。根據(jù)規(guī)則的一致性,對(duì)一個(gè)MIME段被前綴上兩個(gè)連接符('--
'.$BOUNDARY.crlf)并且在最后一個(gè)MIME段的后面,在邊界標(biāo)識(shí)后追加兩個(gè)連接符表示郵件范圍結(jié)束。
在變量$msg中的完整的信息作為這個(gè)方法的值被返回。
下一個(gè)方法,get_email()通過(guò)build_message()方法完成MIME消息的生成。因?yàn)閎uild_message()是一
個(gè)內(nèi)部方法,get_email()在調(diào)用完build_message()之后,創(chuàng)建RFC 822的信息頭并且追加上MIME信息。
<?php
function gen_email($force=false) {
if (!empty($this->email) && !$force) return $this->email ; // saves processing
$email = "";
if (empty($this->subject)) $this->subject = NOSUBJECT;
if (!empty($this->from)) $email .= 'From: '.$this->from.CRLF;
if (!empty($this->headers)) $email .= $this->headers.CRLF;
$email .= $this->build_message();
$this->email = $email;
return $this->email;
}
?>
對(duì)于我們的類的一個(gè)實(shí)例來(lái)說(shuō),類的成員$email擁有生成的整個(gè)郵件信息。為了避免信息被無(wú)必要的重
新生成,這個(gè)方法繼續(xù)創(chuàng)建郵件頭,并且只有當(dāng)$mail為空時(shí)才調(diào)用build_message()。然而,你可以通過(guò)調(diào)
用gen_email()來(lái)強(qiáng)制重新處理。(如果"To"信息被改變或加入了一個(gè)新的附件,調(diào)用者顯示想這么做)。
gen_email()創(chuàng)建了更熟悉的From頭。另外,如果沒(méi)有指定主題,它將主題設(shè)為缺省值(No Subject)。
我們直到后面才將To和Subject 的內(nèi)含保存起來(lái)。這個(gè)方法返回完整的郵件信息,這樣就結(jié)束了創(chuàng)建MIME信
息的任務(wù)。