使用PHP發送郵件,可以使用內置函數mail(),但是使用mail()函數發送郵件,就必須自己配置一臺不需要驗證的SMTP服務器。這樣的話很麻煩.下面,我們是用另外一種方式,使用封裝SMTP協議的郵件類發送郵件,需要引入PHPMailer和SMTP類
本文將以通過郵箱找回密碼這樣一個實例來詳細介紹郵件發送操作步驟,PHP框架使用thinkPHP 3,其它框架也可按照步驟引用.為了突出主題,代碼已盡可能簡化。
### 準備工作
首先要有個郵箱賬號,這里以網易郵箱為例.接下來開啟 POP3/SMTP/IMAP 服務,點擊郵箱里的設置,選擇POP3/SMTP/IMAP.按提示一步步操作。
### ChangePwd控制器
通常點擊通過郵件找回密碼,會跳到郵箱輸入頁面,下面是相應的控制器。
~~~php
<?php
namespace Home\Controller;
use Think\Controller;
class ChangePwdController extends Controller {
//通過郵箱找回密碼
public function findByEmail()
{
$this -> display();
}
//郵件鏈接點擊后跳轉到修改密碼頁面
public function editPwdByMail()
{
$_SESSION ['emailpwd'] = array (
'key' => trim($_GET ['key']),
'info' => trim($_GET ['info']),
'code' => trim($_GET ['code']),
'time' => trim($_GET ['time'])
);
$this->display();
}
//郵箱修改密碼的功能實現
public function doEditPwdByEmail()
{
$str = base64_decode($_SESSION['emailpwd']['info']);
$arr = explode('+',$str); //用戶名和key
$user['username'] = $arr[0];
$reinfo = M('user') ->where($user) -> find();
// 判斷是否在有效期,用時間戳判斷或SESSION有效期判斷,這里為30分鐘
$retime = time();
if(($_SESSION['emailpwd']['code'] == md5('mytime'.$_SESSION['emailpwd']['time'])) && ((($_SESSION['emailpwd']['time']) + (60 * 30)) >= $retime)){
if (md5($reinfo['username'].'+'.$reinfo['password']) == $_SESSION['emailpwd']['key']){ // 判斷URL傳輸中username是否更改
$upid ['id'] = $reinfo ['id'];
if($_POST ['user_password'] == $_POST ['reuser_password'] && $_POST ['user_password'] != '') {
$data['password'] = md5(trim(I('post.reuser_password')));
$edit = M('user') -> where($upid) -> data($data) -> save();
if($edit){
unset($_SESSION ['emailpwd']);
$this -> success('修改成功,請重新登錄!!',U( 'Index/index' ),2);
}else{
$this -> error('修改失敗!!');
}
}else{
$this -> error('兩次輸入密碼不一致,或者密碼為空!');
exit();
}
}else{
//鏈接被更改
$this -> error('鏈接出現錯誤或密碼已經修改,請重試!!',U('Email/index'),3);
}
}else{
//超過30分鐘,無效鏈接,刪除這個session
unset($_SESSION ['emailpwd']);
$this -> error('鏈接失效,請重新申請',U('Email/index'),2);
}
}
}
~~~
### findByEmail模板
~~~
<!DOCTYPE html>
<html?lang="en">
<head>
<meta?charset="UTF-8">
<title>密碼找回</title>
</head>
<body>
<form?action="{:U('Email/SendEmail')}"?method="post">
郵箱地址:<input?type="text"?name='email'><br>
<input?type="submit"?value="提交">
</form>
</body>
</html>
~~~
然后是后臺邏輯代碼
### Email控制器
~~~
<?php?
namespace?Home\Controller;?
use?Think\Controller;?
class?EmailController?extends?Controller?{?
//發送郵件?
public?function?SendEmail()?
{?
$map['email']?=?I('post.email');?
$info?=?M('user')?->?where($map)?->?find();?//查詢信息是否存在?
if($info){?
$key?=?md5($info['username'].'+'.$info['password']);?
$string?=?base64_encode($info['username'].'+'.$key);?// 加密,可解密?
$time?=?time();?
$code?=?md5('mytime'.$time);?
// 生成URL?
$findpwd?=?$_SERVER['HTTP_HOST'].U('ChangePwd/editPwdByMail').'?key='.$key.'&info='.$string.'&time='.$time.'&code='.$code;?// code是用來檢驗time是否有修改過?
$username?=?$info['username'];?
$title?=?"找回密碼";?
$content?=?"<h3>親愛的:$username?用戶</h3> <br><br>http:
//$findpwd?
<br><br><br><h4>有效期30分鐘</h4> <br><br>";?
$from?=?"發件方郵箱地址";?//修改為自己的發送郵箱?
$to?=?$info['email'];?
// 調用發送郵件函數?
$status?=?send_mail($title,$content,$from,$to);?
if($status?==?1){?
$this?->?success?('發送郵件成功...','',2);?
}else{?
$this?->?error('發送郵件失敗...');?
exit();?
}?
}else{?
$this?->?error('此郵箱未注冊');?
exit();?
}?
}
? }
~~~
接下來是send\_mail()函數
### send\_mail()
~~~php
//郵件的配置函數
function send_mail($title,$content,$from,$to,$chart = 'utf-8',$attachment = '') {
import('Common.Util.Email.PHPMailer');
import('Common.Util.Email.SMTP');
$mail = new PHPMailer();
$mail -> CharSet = $chart; // 設置編碼
$mail -> IsSMTP('smtp'); // 設置采用SMTP方式發送郵件
$mail -> Host = "smtp.163.com"; // 設置郵件服務器的地址(例如網易郵箱)
$mail -> Port = 25; // 設置郵件服務器的端口,SMTP默認為25
$mail -> From = $from; // 設置發件人的郵箱地址
$mail -> FromName = "Leon"; // 設置發件人的姓名
$mail -> SMTPAuth = true; // 設置SMTP是否需要密碼驗證,true表示需要
$mail -> Username = "發件方的郵箱"; // 設置發送郵件的郵箱
$mail -> Password = "郵箱密碼"; // 設置郵箱的密碼,可以是獨立密碼
$mail -> Subject = $title; // 設置郵件的標題
$mail -> AltBody = "text/html";
$mail -> Body = $content; // 設置郵件內容
$mail -> IsHTML (true); // 設置內容是否為html類型
$mail -> WordWrap = 50; // 設置每行的字符數
$mail -> AddReplyTo ("地址","名字"); // 設置回復的收件人的地址
$mail -> AddAddress ( $to,"" ); // 設置收件的地址
if($attachment != ''){
$mail->AddAttachment($attachment,$attachment);
}
if ($mail -> Send()){
//$status1 = "$to" . ' 已投送成功<br />';
$status = 1;
}else{
//$status2 = "$to" . ' 發送郵件失敗<br />';
$status = 0;
}
return $status;
}
~~~
前面說的兩個類現在派上用場了,在Thinkphp框架中,請不要改變核心目錄ThinkPHP,我們將外部類放在應用目錄下,如圖所示
:-: 
### 類文件下載
[PHPMailer下載](http://acier.cn/wp-content/uploads/PHPMailer.class.php) ?[SMTP下載](http://acier.cn/wp-content/uploads/SMTP.class.php)
如果操作成功,那么應該就能收到郵件了,郵件里是一個鏈接,有效期為30分鐘(可自行設定),點擊鏈接將訪問ChangePwd控制器editPwdByMail方法
### editPwdByMail模板
~~~
<!doctype html>
<html?lang="en">
<head>
<meta?charset="UTF-8">
<title>通過郵箱設置密碼</title>
<style?type="text/css">?#all{?width:550px;?height:auto;?overflow:?hidden;?margin:0?auto;?}?td{?font-size:14px;?}?input{?border:solid?1px?#ddd;?width:200px;?height:24px;?}?table,td{?border-collapse:?collapse;?padding:10px;?}?span{?font-size:12px;?color:green;?display:none;?}?.active{?border:solid?1px?blue;?}?.error{?border:solid?1px?red;?}?.error-text?{?color:red;?}?.success-text{?color:green;?}?</style>
</head>
<body>
<div>郵箱驗證成功,請輸入新密碼。</div>
<div?id="all">
<form?action="{:U('ChangePwd/doEditPwdByEmail')}"?method="post">
<table>
<tr><td>密碼</td><td><input?remind="請輸入6~20位的非空白字符"?type="password"?name="user_password"><span></span></td></tr>
<tr><td>確認密碼</td><td><input?type="password"?remind="請再次輸入密碼"?name="reuser_password"><span></span></td></tr>
<tr><td></td><td><button>點擊提交</button></td></tr>
</table>
</form>
</div>
<script?type="text/javascript"?src="__PUBLIC__/js/jquery-1.9.0.min.js"></script>
<script?language="javascript">?//檢測變量的聲明?var?CPASS?=?false;?var?CREPASS?=?false;?//綁定獲得焦點事件?$('input').focus(function(){?//獲取當前元素中remind屬性?var?remind?=?$(this).attr('remind');?//顯示?$(this).next().html(remind).removeClass().addClass('success-text').show();?//修改元素的邊框?$(this).addClass('active');?});?//綁定密碼的喪失焦點事件?$('input[name=user_password]').blur(function(){?//獲取密碼的值?var?v?=?$(this).val();?//聲明正則?var?reg?=?/^\S{6,20}$/;?//檢測?var?res?=?reg.test(v);?if(!res){?$(this).next().html('密碼格式不正確').removeClass().addClass('error-text').show();?$(this).removeClass().addClass('error');?CPASS?=?false;?}else{?$(this).next().html('√').removeClass().addClass('success-text');?$(this).removeClass();?CPASS?=?true;?}?});?//確認密碼的喪失焦點事件?$('input[name=reuser_password]').blur(function(){?//獲取密碼的值?var?v?=?$(this).val();?//檢測?var?res?=?$('input[name=user_password]').val()?==?v;?if(!res){?$(this).next().html('兩次密碼不一致').removeClass().addClass('error-text').show();?$(this).removeClass().addClass('error');?CREPASS?=?false;?}else{?$(this).next().html('').removeClass().addClass('success-text');?$(this).removeClass();?CREPASS?=?true;?}?});?//表單提交事件的綁定?$('form').submit(function(){?//觸發元素的喪失焦點事件?$('input[name=user_password]').trigger('blur');?$('input[name=reuser_password]').trigger('blur');?//檢測元素的值?if(CPASS?&&?CREPASS){?return?true;?}?return?false;?});?</script>
</body>
</html>
~~~
至此,密碼已修改完成,發送郵件操作就介紹到這里。