D:\local\PHPnow\php-5.2.14-Win32\pear.bat install Mail
D:\local\PHPnow\php-5.2.14-Win32\pear.bat install Mail_MimeD:\local\PHPnow\php-5.2.14-Win32\pear.bat install Net_SMTP
linux类似:
/usr/local/php/bin/pear install Mail
/usr/local/php/bin/pear install Mail_Mime
/usr/local/php/bin/pear install Net_SMTP
安装完毕重启apache,接下来便是测试了。
(三)Yii框架组件代码测试
先可以参考官网示例:http://pear.php.net/manual/en/package.mail.mail-mime.example.php
include 'Mail.php';
include 'Mail/mime.php' ;
$text = 'Text version of email';
$html = '
HTML version of email';$file = '/home/richard/example.php';
$crlf = "\n";
$hdrs = array(
'From' => 'you@yourdomain.com',
'Subject' => 'Test mime message'
);
$mime = new Mail_mime(array('eol' => $crlf));
$mime->setTXTBody($text);
$mime->setHTMLBody($html);
$mime->addAttachment($file, 'text/plain');
$body = $mime->get();
$hdrs = $mime->headers($hdrs);
$mail =& Mail::factory('mail');
$mail->send('postmaster@localhost', $hdrs, $body);
?>
如以上成功发送邮件,说明php pear mail安装配置成功~
测试成功可发送邮件以后,我们探讨一下如何在Yii框架中配置通用邮件发送模块。
我们使用smarty模版引擎来生成html邮件中的htmlbody内容,搭建Yii框架邮件发送的通用模块,关键在于邮箱账户轻松配置、新邮件内容的smarty模版页面容易添加、邮件发送接口方便调用。Smarty模版引擎的使用这里不再赘述。
先看看要实现的效果:
class SiteController extends Controller
{
/**
* @var string the default layout for the views. Defaults to '//layouts/column2', meaning
* using two-column layout. See 'protected/views/layouts/column2.php'.
*/
public $layout = "//layouts/column2";
public function actionTest()
{
try {
$model = new FormModel();
$model->_test = 1; //此处为FormModel里变量,用于渲染到smarty模版里
$mailSettings = array (
'resetPassword' => array(
'name'=>'wefuture',
'from'=>'support@qq.com',
'to'=>'support@qq.com',
'cc'=>"",
'vipcc'=>"",
'subject'=>'重置密码',
'template'=>'resetPassword.htm',
'attachments'=>array(),
),
);
$model->sendMail($mailSettings, 'resetPassword', "support@qq.com");
} catch(Exception $e) {
var_dump($e->getMessage());
}
}
}如上,发送一封邮件,我们只需要关心好好的填写邮件配置信息,写好“resetPassword”模版引擎内容渲染到邮件中即可,怎么样,是不是很方便。
接着我们看看FormModel里函数做了些什么:
/**
* Controller is the customized base controller class.
* All controller classes for this application should extend from this base class.
*/
class FormModel extends CFormModel
{
public $_test;
public function init() {
}
/**
* auto trim all
*/
public function setAttributes($values, $safeOnly=true)
{
if (is_array($values)) {
foreach ($values as $name => $val) {
if (is_string($val)) {
$values[$name] = trim($val);
}
}
}
return parent::setAttributes($values,$safeOnly);
}
/**
* auto trim all
*/
public function beforeValidate()
{
if (is_array($this->attributes)) {
foreach ($this->attributes as $name => $val) {
if (is_string($val)) {
$this->$name = trim($val);
}
}
}
return parent::beforeValidate();
}
/**
* 发送邮件函数
*
*/
public function sendMail($mailSettings, $settingName, $TO = null, $CC = null ,$setPage=1) {
if(!isset($mailSettings[$settingName])){
echo "mail setting for $settingName not found!";
die();
}
$mailSetting = $mailSettings[$settingName];
$attachments = array();
if (isset($mailSetting['attachments']) && $setPage == 1) {
foreach($mailSetting['attachments'] as $key=>$value) {
$attachments[]=$value;
}
}
if($TO) { //如果指定收件人
$to = $TO;
} else {
$to = $mailSetting['to'];
}
if($CC) { //如果指定抄送人
$cc = $CC;
} else {
$cc = $mailSetting['cc'];
}
if(isset($this->isContainVip)
&& $this->isContainVip
&& isset($mailSetting['vipcc'])
&& strlen($mailSetting['vipcc']) > 0){
$vipcc = $mailSetting['vipcc'];
$cc = $cc . "," . $vipcc;
}
$subject = $mailSetting['subject'];
$from = $mailSetting['from'];
$name = $mailSetting['name'];
$html = true;
$data = array(
'model' => $this,
);
$ret = Yii::app()->messenger->sendSmartyMail($to, $cc, $subject, $mailSetting['template'], $data, $from, $name, $html, $attachments);
if ($ret == false) {
$this->addError('email', '发送邮件失败');
return false;
} else {
Yii::log('发送邮件成功, subject: ' . $subject, 'info');
}
return true;
}
}
代码里用到,Yii::app()->messenger->sendSmartyMail,我在工程里自己配置了组件messager、smarty,看看messager文件类内容:
require_once('Mail.php');
require_once('Mail/mime.php');
/**
* class Messenger.
*
* 发送邮件
*
* 支持html格式和纯文本格式;
* 支持使用应用对应的smarty模版生成邮件内容;
* 支持发送附件
*
* 所有的邮件内容,变量使用utf-8编码
*/
class Messenger
{
public $mailer;
public $options;
public function init() {
if (empty($this->mailer)) {
$this->mailer = 'mail';
}
}
/**
* 发送使用smarty模板的邮件
*
* 使用系统配置的smarty模板路径下的 mail/$template.html作为模板文件
*
* @param string $to 逗号分隔的收件人列表
* @param string $subject 邮件的主题
* @param string $template 模版名称
* @param array $data 需要替换的模版变量数组($template_var => $template_value)
* @param string $from 发件人的email
* @param string $name 发件人的显示名
* @param boolean $html 邮件是否是html格式,默认为true
* @param array $attachments 附件文件路径列表,默认为空
*/
public function sendSmartyMail($to, $cc, $subject, $template, $data, $from, $name, $html=true, $attachments=array()) {
if (!isset($to) || ($to == "")) {
return;
}
if (!isset($cc) || ($cc == "")) {
$cc = '';
}
// 可以配置将所有邮件都发到一个邮件地址或列表
// 用于测试时,避免发出垃圾邮件骚扰大家
$sendAllMailTo = Yii::app()->params['DEBUG_SEND_ALL_MAIL_TO'];
if (!empty($sendAllMailTo)) {
$to = $sendAllMailTo;
$cc = $sendAllMailTo;
}
$smarty = Yii::app()->smarty;
$smarty->assign($data);
$content = $smarty->fetch('mail/'.$template);
$hdrs = array(
'Return-Path' => $from,
'From' => "$name ",
'To' => $to,
'Subject' => "=?UTF-8?B?".base64_encode($subject)."?=",
'Date' => date("r"),
);
if($cc != ""){
$ccHeader = array('Cc' => $cc);
$hdrs = array_merge($hdrs, $ccHeader);
}
$param = array(
'text_charset' => 'utf-8',
'head_charset' => 'utf-8',
'html_charset' => 'utf-8',
);
$mime = new Mail_mime();
if ($html){
$mime->setHtmlBody($content);
}
else{
$mime->setTXTBody($content);
}
foreach ($attachments as $att) {
$mime->addAttachment($att);
}
$body = @$mime->get($param);
$hdrs = @$mime->headers($hdrs);
$email = &Mail::factory($this->mailer, $this->options);
/**
* 2011年3月的Net_SMTP有个bug,对timeout的处理有问题,而PEAR的Mail_smtp类并没有正确的初始化Net_SMTP
* 导致Net_SMTP对timeout的bug传递出来。如果在smtp对象上调用connect方法后(getSMTPObject以后),
* 再调用setTimeout(新版Net_SMTP才有),则问题可以绕过。
* 该问题只在PEAR Net_SMTP v1.5.0和v1.5.1上存在
* see https://pear.php.net/bugs/bug.php?id=18335&edit=12&patch=Net_SMTP-bug18335.diff&revision=latest
*/
$result = &$email->getSMTPObject();
if (PEAR::isError($result)) {
Yii::log('初始化SMTP对象失败:'.$result->getMessage(), 'error');
return $false;
}
// workaround Net_SMTP bug
if (method_exists($result, 'setTimeout')) {
$result->setTimeout(3600); // 1 hour
}
//只有放到recipients里,才会收到邮件。至于显示到To还是Cc由header决定。
$recipients = isset($hdrs['Cc'])? $hdrs['To'].','.$hdrs['Cc']:$hdrs['To'];
$ret = $email->send($recipients, $hdrs, $body);
if (PEAR::isError($ret)) {
Yii::log('发送邮件错误:'.$ret->getMessage(), 'error');
return false;
} else {
Yii::log('发送邮件成功,Subject: ' . $subject, 'info');
}
return true;
}
/**
* 发送邮件
*
* @param string $to 逗号分隔的收件人列表
* @param string $subject 邮件的主题
* @param array $content 邮件内容
* @param boolean $html 邮件是否是html格式,默认为否
* @param string $from 发件人的email
* @param string $name 发件人的显示名
* @param array $attachments 附件文件路径列表
*/
public function sendMail($to, $subject, $content, $html=false, $from="support@qq.com", $name="wefuture", $attachments=array()) {
if (!isset($to) || ($to == "")) {
return;
}
// 可以配置将所有邮件都发到一个邮件地址或列表
// 用于测试时,避免发出垃圾邮件骚扰大家
$sendAllMailTo = Yii::app()->params['DEBUG_SEND_ALL_MAIL_TO'];
if (!empty($sendAllMailTo)) {
$ori = $to;
$to = $sendAllMailTo;
$content = "原邮件接收人:".$ori."\n 现接收人:".$sendAllMailTo." \n 内容是:\n ".$content;
}
$hdrs = array(
'Return-Path' => $from,
'From' => "$name ",
'Subject' => $subject,
);
$param = array(
'text_charset' => 'UTF-8',
'head_charset' => 'UTF-8',
'html_charset' => 'UTF-8',
);
$mime = new Mail_mime();
if ($html) {
$mime->setHtmlBody($content);
}
else {
$mime->setTXTBody($content);
}
foreach ($attachments as $att) {
$mime->addAttachment($att);
}
$body = @$mime->get($param);
$hdrs = @$mime->headers($hdrs);
$email = &Mail::factory($this->mailer, $this->options);
$ret = $email->send($to, $hdrs, $body);
if (PEAR::isError($ret)) {
Yii::log('发送邮件错误:'.$ret->getMessage(), 'error');
return false;
}
return true;
}
}
上面一个类就挺简单了,用到了smarty、php pear mail模块。最后再贴出一下main.php的config配置加入一下代码:
'smarty' => array(
'class'=>'lib.thirdparty.CSmarty',
'templatePath' => $WEB_BASE_DIR.'/smarty',
),
'messenger' => array(
'class' => 'lib.common.Messenger',
'mailer' => 'smtp',
'options' => array(
'auth' => true,
'host' => 'smtp.exmail.qq.com',
'username' => 'support@qq.com',
'password' => 'xxxxxxxxx',
),
),
至此,基于Yii框架利用php pear mail发送html邮件的配置工作就完成啦~
以上Yii框架适合对Yii框架经验较丰富者参考,直接复制可能不行很好运行,仅提供一种思路和核心代码。