如果在Windows環境下使用Zend_Mail寄信,而且是使用Zend_Mail_Transport_Sendmail當作transport,addBcc()基本上無效,所有收件者仍然會顯示出來。因為Zend_Mail會將addTo(), addCc(), addBcc()這些方法指定的email全部當成是收件者,也就是php函數mail()的$to參數。如此一來,所有的收件者自然就全部顯示了。但如果使用Zend_Mail_Transport_Smtp當作transport,運作則完全正常。
網路上有人說可以將Zend_Mail的 getRecipients改成下列狀態。
public function getRecipients()
{
return $this->_to;//array_keys($this->_recipients);
}
$this->_recipients就是所有的to, cc, bcc的email。不過如此一來,當transport是Zend_Mail_Transport_Smtp時,其他非to的email就完全收不到信了,因為Zend_Mail_Transport_Smtp也是使用上述函數傳回的email當作收件者。看來在不改寫Zend_Mail的情況下,如果有非addTo的動作,似乎無法同時透過Zend_Mail實行sendmail和smtp的模式。
我發現也可以針對Zend_Mail_Transport_Sendmail的_prepareHeaders()來修改,但不要和上述的修改一起做。其中有一段是判別伺服器是否是windows環境,如果不是的話,就使用Zend_Mail類別的實體的header[‘to’]屬性重新指定收件者,這樣addTo的收件者就可以替換掉官方版的Zend_Mail的getRecipients()回傳的所有的收件者,而cc, bcc仍然是副本和密件副本。但奇怪就在這裡,如果伺服器是windows就不這麼做,實在不懂的為什麼。所以我將縮減Zend_Mail_Transport_Sendmail的_prepareHeaders()成為下列所示內容。
protected function _prepareHeaders($headers)
{
if (!$this->_mail) {
/**
* @see Zend_Mail_Transport_Exception
*/
require_once ‘Zend/Mail/Transport/Exception.php’;
throw new Zend_Mail_Transport_Exception(‘_prepareHeaders requires a registered Zend_Mail object’);
}if (!isset($headers[‘To’])) {
/**
* @see Zend_Mail_Transport_Exception
*/
require_once ‘Zend/Mail/Transport/Exception.php’;
throw new Zend_Mail_Transport_Exception(‘Missing To header’);
}unset($headers[‘To’][‘append’]);
$this->recipients = implode(‘,’, $headers[‘To’]);// Remove recipient header
unset($headers[‘To’]);// Remove subject header, if present
if (isset($headers[‘Subject’])) {
unset($headers[‘Subject’]);
}// Prepare headers
parent::_prepareHeaders($headers);// Fix issue with empty blank line ontop when using Sendmail Trnasport
$this->header = rtrim($this->header);
}
另外再說明一點,sendmail的模式下,to一定得指定,不指定就會有錯誤。smtp則不一定需要指定to,因為所有的to, cc, bcc都是收件者,只要其中有任何一個類別的收件者有指定就可以了。