最近做一個項目需要添加發郵件的功能,一次我收集了一些郵件配置的功能。並且實現將Yii移植到BAE上時實現同樣的功能,向某個郵箱發送一份BAE的消息郵件,分享給大家,希望能給大家帶來幫組。
本地Yii實現發郵件實例:
步驟一:
下載Yii的mailer擴展:
官方擴展鏈接:http://www.yiiframework.com/extension/mailer/
下載後解壓放置在protected/extensions/下
步驟二:
申請一個郵箱作爲發件箱,以下我們以163郵箱爲例
步驟三:
public function actionMail(){ $message = 'mail success!!!'; $mailer = Yii::createComponent('application.extensions.mailer.EMailer'); $mailer->Host = 'smtp.163.com'; $mailer->IsSMTP(); $mailer->SMTPAuth = true; $mailer->From = '[email protected]'; //設置發件地址 $mailer->AddReplyTo('[email protected]'); $mailer->AddAddress('[email protected]'); //設置收件件地址 $mailer->FromName = 'XXXXXX'; //這裏設置發件人姓名 $mailer->Username = '[email protected]'; //這裏輸入發件地址的用戶名 $mailer->Password = 'XXXX'; //這裏輸入發件地址的密碼 $mailer->SMTPDebug = true; //設置SMTPDebug爲true,就可以打開Debug功能,根據提示去修改配置 $mailer->CharSet = 'UTF-8'; $mailer->Subject = Yii::t('demo', 'Yii rulez!'); //設置郵件的主題 $mailer->Body = $message; $mailer->Send(); }
步驟四:
在瀏覽器中輸入http://hostname/index.php?r=site/mail, 查看收件箱看是否收到郵件。如果設置正確一般不會出什麼問題。
由於我們需要把應用部署到雲端,而云端禁用mail函數,這是我們需要使用BAE給我提供的API來實現郵件服務。我們如果瞭解百度雲定製的Yii框架,我們可以使用email郵箱來接受Yii運行的一些調試信息。這各主要是通過,CEmailLog類來實現這一功能,而百度雲的定製框架上也實現了這個類。但需要更改一些東西。
更改/framework/baeconfig目錄下的baeconfig.php文件,添加消息隊列和收件箱。
'log'=>array( 'class'=>'CLogRouter', 'routes'=>array( array( 'class'=>'CBaeLogRoute', 'levels'=>'error, warning,trace', ), array( 'class'=>'CEmailLogRoute', 'levels'=>'error, warning', 'queueName'=>'XXXXXXXX', //這裏是消息隊列的名稱 'emails'=>'[email protected]',//這裏是收件箱的名稱 ), ), ),
下面我貼出BAE的CEmailLog類的實現代碼:
<?php /** * CEmailLogRoute class file. * * @author Qiang Xue <[email protected]> * @link http://www.yiiframework.com/ * @copyright Copyright © 2008-2011 Yii Software LLC * @license http://www.yiiframework.com/license/ */ /** * CEmailLogRoute sends selected log messages to email addresses. * * The target email addresses may be specified via {@link setEmails emails} property. * Optionally, you may set the email {@link setSubject subject}, the * {@link setSentFrom sentFrom} address and any additional {@link setHeaders headers}. * * @property array $emails List of destination email addresses. * @property string $subject Email subject. Defaults to CEmailLogRoute::DEFAULT_SUBJECT. * @property string $sentFrom Send from address of the email. * @property array $headers Additional headers to use when sending an email. * * @author Qiang Xue <[email protected]> * @version $Id: CEmailLogRoute.php 3426 2011-10-25 00:01:09Z alexander.makarow $ * @package system.logging * @since 1.0 */ class CEmailLogRoute extends CLogRoute { /** * @var array list of destination email addresses. */ private $_email=array(); /** * @var string email subject */ private $_subject; /** * @var string email sent from address */ private $_from; /** * @var array list of additional headers to use when sending an email. */ private $_headers=array(); /** *the queueName of BCMS */ public $queueName=''; /** *initilize the queueName */ public function __construct($queueName='') { $this->queueName=$queueName; } /** * Sends log messages to specified email addresses. * @param array $logs list of log messages */ protected function processLogs($logs) { $message=''; foreach($logs as $log) $message.=$this->formatLogMessage($log[0],$log[1],$log[2],$log[3]); $message=wordwrap($message,70); $subject=$this->getSubject(); if($subject===null) $subject=Yii::t('yii','Application Log'); if(IS_BAE) { $this->sendEmail($this->getEmails(),$subject,$message); } else { foreach($this->getEmails() as $email) $this->sendEmail($email,$subject,$message); } } /** * Sends an email. * @param string $email single email address * @param string $subject email subject * @param string $message email content */ protected function sendEmail($email,$subject,$message) { if(IS_BAE) { require_once ( "Bcms.class.php" ) ; $bcms = new Bcms(); $ret = $bcms->mail ( $this->queueName, $message,json_encode($email)) ; if ( false === $ret ) { Yii::trace("send log to email is failed"); } else { Yii::trace("send log to email success"); } } else { $headers=$this->getHeaders(); if(($from=$this->getSentFrom())!==null) $headers[]="From: {$from}"; mail($email,$subject,$message,implode("\r\n",$headers)); } } /** * @return array list of destination email addresses */ public function getEmails() { return $this->_email; } /** * @param mixed $value list of destination email addresses. If the value is * a string, it is assumed to be comma-separated email addresses. */ public function setEmails($value) { if(IS_BAE) { if(is_array($value)) $this->_email=$value; else $this->_email=preg_split('/[\s,]+/',$value,-1,PREG_SPLIT_NO_EMPTY); } else { if(is_array($value)) $this->_email=$value; else $this->_email=preg_split('/[\s,]+/',$value,-1,PREG_SPLIT_NO_EMPTY); } } /** * @return string email subject. Defaults to CEmailLogRoute::DEFAULT_SUBJECT */ public function getSubject() { return $this->_subject; } /** * @param string $value email subject. */ public function setSubject($value) { $this->_subject=$value; } /** * @return string send from address of the email */ public function getSentFrom() { return $this->_from; } /** * @param string $value send from address of the email */ public function setSentFrom($value) { $this->_from=$value; } /** * @return array additional headers to use when sending an email. * @since 1.1.4 */ public function getHeaders() { return $this->_headers; } /** * @param mixed $value list of additional headers to use when sending an email. * If the value is a string, it is assumed to be line break separated headers. * @since 1.1.4 */ public function setHeaders($value) { if (is_array($value)) $this->_headers=$value; else $this->_headers=preg_split('/\r\n|\n/',$value,-1,PREG_SPLIT_NO_EMPTY); } }
BAE上發送郵件通過bae的雲消息API的Mail函數實現的。
public function mail($queueName,$message,$address,$optional=array())
以下是我修改後的Mailer類(仿CEmailLog)
<?php class Mailer{ /** * @var array list of destination email addresses. */ private $_email=array(); /** * @var string email subject */ private $_subject; /** * @var string email sent from address */ private $_from; /** * @var array list of additional headers to use when sending an email. */ private $_headers=array(); /** *the queueName of BCMS */ public $queueName='XXXXXXXXXXXXXXXXXXXXXXXXXXX'; //這裏填你的消息隊列的名稱 /** *initilize the queueName */ public function __construct() { include_once ( "Bcms.class.php" ) ; } /** * Sends an email. * @param string $email single email address * @param string $subject email subject * @param string $message email content */ public function sendEmail($email,$subject,$message) { if(IS_BAE) { $log = new Log; $bcms = new Bcms(); $ret = $bcms->mail ( $this->queueName, $message,array($email)) ; if ( false === $ret ) { $log->fb("send log to email is failed"); Yii::trace("send log to email is failed"); } else { $log->fb("send log to email success"); Yii::trace("send log to email success"); } } else { $headers=$this->getHeaders(); if(($from=$this->getSentFrom())!==null) $headers[]="From: {$from}"; mail($email,$subject,$message,implode("\r\n",$headers)); } } /** * @return array list of destination email addresses */ public function getEmails() { return $this->_email; } /** * @param mixed $value list of destination email addresses. If the value is * a string, it is assumed to be comma-separated email addresses. */ public function setEmails($value) { if(IS_BAE) { if(is_array($value)) $this->_email=$value; else $this->_email=preg_split('/[\s,]+/',$value,-1,PREG_SPLIT_NO_EMPTY); } else { if(is_array($value)) $this->_email=$value; else $this->_email=preg_split('/[\s,]+/',$value,-1,PREG_SPLIT_NO_EMPTY); } } /** * @return string email subject. Defaults to CEmailLogRoute::DEFAULT_SUBJECT */ public function getSubject() { return $this->_subject; } /** * @param string $value email subject. */ public function setSubject($value) { $this->_subject=$value; } /** * @return string send from address of the email */ public function getSentFrom() { return $this->_from; } /** * @param string $value send from address of the email */ public function setSentFrom($value) { $this->_from=$value; } /** * @return array additional headers to use when sending an email. * @since 1.1.4 */ public function getHeaders() { return $this->_headers; } /** * @param mixed $value list of additional headers to use when sending an email. * If the value is a string, it is assumed to be line break separated headers. * @since 1.1.4 */ public function setHeaders($value) { if (is_array($value)) $this->_headers=$value; else $this->_headers=preg_split('/\r\n|\n/',$value,-1,PREG_SPLIT_NO_EMPTY); } }
步驟二:
實現Mailaction:
public function actionMail(){ $message = 'Hello World!'; $mailer = new Mailer; $log->fb($mailer); $mailer->sendEmail('[email protected]','Yii rulez!',$message); }
步驟三:
在瀏覽器中輸入http://hostname/index.php?r=site/mail, 查看收件箱是否收到BAE的郵件。