1.安裝composer
2.設定composer為全局變量
3.進入項目目錄
4.在指令行執行:composer require phpmailer/phpmailer
5.建立Test.controller控制器檔案,代碼如下:
<?php
/**
* Created by PhpStorm.
* User: dyane
* Date: 2019/3/29
* Time: 16:38
*/
namespace app\system_admin\controller;
use think\Request;
class Test
{
/**
* 郵件發送頁面
* @return mixed
*/
public function index()
{
return view('email/index');
}
/**
* 發送郵件
*/
public function send()
{
if($this->request->isPost()) {
$param = $this->request->param();
//判斷收件人
if (empty($param['addressee'])) {
return json(['code' => 400, 'msg' => '收件人位址不能為空!']);
die;
}
//判斷郵件主題和内容必須存在一個
if (empty($param['title']) && empty($param['content'])) {
return json(['code' => 400, 'msg' => '主題和内容必須填寫一個!']);
die;
}
//擷取收件人位址
$addressee = $param['addressee'];
//驗證郵箱
$addressee = $this->checkEmailStr($addressee);
//擷取主題或内容
if (!empty($param['title'])) {
$title = htmlspecialchars($param['title']);
} else {
$title = ' ';
}//空格不能去,否則發送失敗
if (!empty($param['content'])) {
$content = $param['content'];
} else {
$content = ' ';
}//空格不能去,否則發送失敗
//擷取抄送人位址
if (!empty($param['copyperson'])) {
$copyerArray = $this->checkEmailStr($param['copyperson']);
} else {
$copyerArray = '';
}
//擷取密送人位址
if (!empty($param['secretagent'])) {
$sercreterArray = $this->checkEmailStr($param['secretagent']);
} else {
$sercreterArray = '';
}
//擷取附件
if (!empty($param['files_list'])) {
$filesArray = $this->checkFiles($param['files_list']);
} else {
$filesArray = '';
}
$res = $this->sendEmail($addressee,$copyerArray,$sercreterArray,$filesArray,$title,$content);
//回報發送結果
if($res){
if (!empty($filesArray)) {
$this->deleteOldEmaileFiles($filesArray);
}
echo json_encode(['code' => 200, 'msg' => '發送成功!']);die;
}else{
echo json_encode(['code' => 400, 'msg' => '發送失敗!']);die;
}
}
}
/**
* 發送郵件
* @param $addressee
* @param $copyerArray
* @param $sercreterArray
* @param $filesArray
* @param $title
* @param $content
*/
protected function sendEmail($addressee,$copyerArray,$sercreterArray,$filesArray,$title,$content)
{
//使用發送郵件類
$mail = new EmailYX();
//設定收件人
$mail->setManyAddressee($addressee);
if(!empty($copyerArray)){$mail->setManyCC($copyerArray);}
if(!empty($sercreterArray)){$mail->setManyBCC($sercreterArray);}
if(!empty($filesArray)){$mail->setManyAttachment($filesArray);}
//設定主題和内容
$mail->setContent($title,$content);
//發送郵件
$res = $mail->send();
return $res;
}
/**
* 發送成功之後删除附件檔案
* @param $filesArray
*/
protected function deleteOldEmaileFiles($filesArray)
{
foreach ($filesArray as $key => $value){
$path = ROOT_PATH . 'public'.$value;
if(file_exists($path)){
unlink($path);
}
}
}
/**
* 驗證郵箱是否正确
* @param $str
*/
protected function checkEmailStr($emailStr)
{
$toArray = explode(',',$emailStr);
$res = $this->checkManyEmail($toArray);
return $res;
}
/**
* 判斷多組字元竄郵箱是否有不正确的郵箱存在
* @param $toArray
* @return bool
*/
protected function checkManyEmail($toArray)
{
foreach ($toArray as $key => $value){
$check = $this->checkEmail($value);
if(!$check){unset($toArray[$key]);}
}
return $toArray;
}
/**
* 正則驗證郵箱是否合法
* @param $email
* @return false|int
*/
protected function checkEmail($email)
{
// $pregEmail='/^[a-zA-Z0-9]+([-_.][a-zA-Z0-9]+)*@([a-zA-Z0-9]+[-.])+([a-z]{2,5})$/ims';
$pregEmail = '/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$/';
$res = preg_match($pregEmail,$email);
return $res;
}
/**
* 處理郵件附件字元串
* @param $filesStr
* @return array
*/
protected function checkFiles($filesStr)
{
$filesStr = trim($filesStr);
$filesStr = rtrim($filesStr,',');
$res = explode(',',$filesStr);
return $res;
}
}
6.封裝設定郵件發送參數類Email.controller檔案,代碼如下:
<?php
/**
* Created by PhpStorm.
* User: dyane
* Date: 2019-03-21
* Time: 10:10
*/
namespace app\system_admin\controller;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
vendor('autoload.php');
class Email
{
const SMTPDebug = 0;
const HOST = 'smtp.qq.com';
const USERNAME = '你的QQ号@qq.com';
const PASSOWRD = 'SMTP授權碼,非QQ郵箱密碼';
const CHARSET = 'UTF-8';
const SMTPAUTH = true;
const ISHTML = true;
const SMTPSECURE = 'ssl';
const PORT = 465;
static $addressee = array();
static $sender = array('a'=>'你的QQ号@qq.com','n'=>'測試系統郵件');
static $cc = array();
static $bcc = array();
static $attachment= array();
static $title = '';
static $body = '';
static $altBody = '';
private $mail = null;
function __construct()
{
$this->mail = new PHPMailer();
}
//初始化參數
public function start()
{
$this->mail->SMTPDebug = self::SMTPDebug;
$this->mail->Host = self::HOST;
$this->mail->CharSet = self::CHARSET;
$this->mail->SMTPAuth = self::SMTPAUTH;
$this->mail->Username = self::USERNAME;
$this->mail->Password = self::PASSOWRD;
$this->mail->SMTPSecure = self::SMTPSECURE;
$this->mail->Port = self::PORT;
if(self::SMTPSECURE == 'ssl'){
$this->mail->SMTPOptions = array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
);
}
$this->mail->isHTML(self::ISHTML);
}
//發送人
public function setSender($address,$senderName = '')
{
self::$sender['a'] = $address;
self::$sender['n'] = $senderName;
}
//收件人回複的位址
public function setReplyAddress($address = '', $replayName = '')
{
self::$sender['a'] = $address;
self::$sender['n'] = $replayName;
}
//單個接收人
public function setAddressee($address,$recName = '')
{
call_user_func_array([$this, 'setAddress'],['addressee',$address, $recName]);
}
//多個接收人
public function setManyAddressee($array)
{
array_walk($array,function($v, $k){
$this->setAddressee($v);
});
}
//抄送單個
public function setCC($address = '', $name = '')
{
call_user_func_array([$this, 'setAddress'],['cc',$address, $name]);
}
//抄送多個
public function setManyCC($array)
{
array_walk($array,function($v, $k){
$this->setCC($v);
});
}
//暗抄送單個
public function setBCC($address = '', $name = '')
{
call_user_func_array([$this, 'setAddress'],['bcc',$address, $name]);
}
//暗抄送單個
public function setManyBCC($array)
{
array_walk($array,function($v, $k){
$this->setBCC($v);
});
}
//附件單個
public function setAttachment($address, $newName = '')
{
call_user_func_array([$this, 'setAddress'],['attachment',$address, $newName]);
}
//附件多個
public function setManyAttachment($array)
{
array_walk($array,function($v, $k){
$this->setAttachment($v);
});
}
public function setAddress($param, $address, $name)
{
array_push(self::${$param}, [
'a'=>$address,'n'=>$name
]
);
}
public function setContent($title = '', $body='', $table = '', $altBody='')
{
self::$title = $title;
if($table) $body = $body.'<br/>'.$table;
self::$body = $body;
self::$altBody = $altBody;
}
//發送郵件
public function send()
{
$res = false;
try {
$this->mail->isSMTP();
$this->start();
$this->mail->setFrom(self::$sender['a'], self::$sender['n']);
$this->mail->addReplyTo(self::$sender['a'], self::$sender['n']);
$this->addAddress(self::$addressee,'addAddress');
$this->addAddress(self::$bcc,'addBCC');
$this->addAddress(self::$cc,'addCC');
$this->addAddress(self::$attachment,'addAttachment');
$this->mail->Subject = self::$title;
$this->mail->Body = self::$body;
$this->mail->AltBody = self::$altBody;
$result = $this->mail->send();
$this->mail->isSMTP();
$result && $res = true;
}catch (Exception $e){
// YXLog::error('Mailer Error: ' . $this->mail->ErrorInfo);
}
return $res;
}
public function addAddress($address,$func)
{
foreach ($address as $item){
$item['a'] && $this->mail->{$func}($item['a'], $item['n']);
}
}
public function setTable($th = array(), $data = array(), $title = '')
{
$table_data = '<table cellpadding="2" cellspacing="0" style="font-size: 12px;">';
$title && $table_data .= '<caption>'.$title.'</caption>';
$table_data .= $this->setTh($th);
$table_data .= $this->setTd($data);
$table_data .= '</table>';
return $table_data;
}
public function setTd($td = array())
{
$data = '';
foreach ($td as $item){
$data .= '<tr>';
foreach ($item as $value){
$data .= '<td>'.$value.'</td>';
}
$data .= '</tr>';
}
return $data;
}
public function setTh($th = array())
{
$data = '<tr>';
foreach ($th as $item){
$data .='<th>'.$item.'</th>';
}
$data .= '</tr>';
return $data;
}
}
7.前段頁面代碼,前端本人使用的是layui架構:
{include file='common/head'}
<div style="overflow-x: hidden;width: 96%;margin: auto;padding-top: 1rem;">
<blockquote class="layui-elem-quote"><span>測試子產品 郵件發送 (<span style="color: red;margin-right: 0.2rem;font-size: 20px;">*</span>為必填 | 多個郵箱之間用","号隔開)</span></blockquote>
<div class="demoTable layui-form" action="" method="post" style="margin-top: 3rem">
<div class="layui-form-item">
<label class="layui-form-label"><span style="color: red;margin-right: 0.2rem;font-size: 20px">*</span>收件人</label>
<div class="layui-input-block">
<input type="text" lay-verify="required" name="addressee" placeholder="請輸入收件人郵箱" autocomplete="off" class="layui-input">
<button class="layui-btn layui-btn-radius chao" style="margin-top:0.5rem">抄送</button>
<button class="layui-btn layui-btn-radius layui-btn-normal mi" style="margin-top:0.5rem">密送</button>
</div>
</div>
<div class="layui-form-item input-chao" style="display: none">
<label class="layui-form-label">抄送人</label>
<div class="layui-input-block">
<input type="text" name="copyperson" placeholder="請輸入抄送人郵箱" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item input-mi" style="display: none;">
<label class="layui-form-label">密送人</label>
<div class="layui-input-block">
<input type="text" name="secretagent" placeholder="請輸入密送人郵箱" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">主題</label>
<div class="layui-input-block">
<input type="text" name="title" placeholder="請輸入郵件主題" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">附件</label>
<div class="layui-input-block">
<blockquote class="layui-elem-quote layui-quote-nm" style="margin-top: 10px;">
<div id="uploadImg" class="layui-upload">
<button type="button" class="layui-btn" id="upload">選擇檔案</button>
<div class="layui-upload-list">
<table class="layui-table" style="text-align: center;">
<thead>
<tr>
<th style="text-align: center;">檔案名</th>
<th style="text-align: center;">大小</th>
<th style="text-align: center;">狀态</th>
<th style="text-align: center;">操作</th>
</tr>
</thead>
<tbody id="imgList"></tbody>
</table>
</div>
<button type="button" class="layui-btn" id="startUpload">開始上傳</button>
</div>
<input type="text" name="files_list" id="imgInput" style="display: none;">
</blockquote>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">郵件内容</label>
<div class="layui-input-block" style="width: 1220px;height: 300px">
<textarea id="demo" name="content" lay-verify="content" lay-verify="required"></textarea>
</div>
</div>
<div class="layui-form-item" style="margin-top: 2rem">
<div class="layui-input-block">
<button class="layui-btn" lay-submit="" lay-filter="demo1">發送</button>
</div>
</div>
</div>
</div>
{include file='common/footer'}
<script>
layui.use(['table', 'form', 'element', 'upload', 'layedit'], function () {
var table = layui.table;
var form = layui.form;
var element = layui.element;
var $ = layui.jquery;
var upload = layui.upload;
var layedit = layui.layedit;
// //建立一個編輯器
layedit.set({
uploadImage:{
url:'{:url("Upload/editUpload")}',
type:'post'
}
});
var editIndex = layedit.build('demo', {
tool: [
'strong' //加粗
,'italic' //斜體
,'underline' //下劃線
,'del' //删除線
,'|' //分割線
,'left' //左對齊
,'center' //居中對齊
,'right' //右對齊
,'image'
],
});
//
//自定義驗證規則
form.verify({
content: function(value){
layedit.sync(editIndex);
}
});
//多檔案清單示例
var demoListView = $('#imgList');
var totalArray = new Array();
var uploadInst = upload.render({
elem: '#upload' //綁定元素
, url: '{:url("Upload/file_images")}' //上傳接口
, accept: 'file' // 允許上傳的檔案類型
// , acceptMime: 'image/jpg,image/png' // (隻支援jpg和png格式,多個用逗号隔開),
, size: 5120 // 最大允許上傳的檔案大小 機關 KB
, auto: false //選擇檔案後不自動上傳
, bindAction: '#startUpload' //指向一個按鈕觸發上傳
, multiple: true // 開啟多檔案上傳
, number: 6 // 同時上傳檔案的最大個數
, choose: function (obj) {
console.log(obj)
var files = this.files = obj.pushFile(); //将每次選擇的檔案追加到檔案隊列
var arr = Object.keys(files);
totalArray = totalArray.concat(arr);
// 檢查上傳檔案的個數
if (totalArray.length <= 6) {
//讀取本地檔案
obj.preview(function (index, file, result) {
var tr = $(['<tr id="upload-' + index + '">'
, '<td>'+file.name+'</td>'
, '<td>' + (file.size / 1014).toFixed(1) + 'kb</td>'
, '<td>等待上傳</td>'
, '<td>'
, '<button class="layui-btn demo-reload layui-hide">重傳</button>'
, '<button class="layui-btn layui-btn-danger demo-delete">删除</button>'
, '</td>'
, '</tr>'].join(''));
//單個重傳
tr.find('.demo-reload').on('click', function () {
obj.upload(index, file);
});
//删除
tr.find('.demo-delete').on('click', function () {
delete files[index]; //删除對應的檔案
tr.remove();
uploadListIns.config.elem.next()[0].value = ''; //清空 input file 值,以免删除後出現同名檔案不可選
});
demoListView.append(tr);
});
} else {
// 超出上傳最大檔案
layer.msg("上傳檔案最大不超過6個")
}
}
, done: function (res, index, upload) {
if (res.code == 0) { //上傳成功
// 上傳成功後将圖檔路徑拼接到input中,多個路徑用","分割
var inputVal = document.getElementById("imgInput").value;
var valData = "";
if (inputVal) {
valData = inputVal + "," + res.data.src;
} else {
valData = res.data.src;
}
document.getElementById("imgInput").value = valData;
var tr = demoListView.find('tr#upload-' + index)
, tds = tr.children();
tds.eq(2).html('<span style="color: #5FB878;">上傳成功</span>');
tds.eq(3).html(''); //清空操作
return delete this.files[index]; //删除檔案隊列已經上傳成功的檔案
}
this.error(index, upload);
}
, error: function (index, upload) {
var tr = demoListView.find('tr#upload-' + index)
, tds = tr.children();
tds.eq(2).html('<span style="color: #FF5722;">上傳失敗</span>');
tds.eq(3).find('.demo-reload').removeClass('layui-hide'); //顯示重傳
}
});
var url='{:url("EmailSend/send")}';
form.on('submit(demo1)', function(data){
layer.msg('郵件正在發送中,請稍後.....',{time:2000},function(){
$.post(url,data.field,function (obj) {
if(obj.code==200){
parent.layer.msg(obj.msg, {icon: 6,time: 1000});
window.location.reload();
}
if(obj.code==400){
parent.layer.msg(obj.msg, {icon: 5,time: 1000});
}
},"JSON");
})
});
//抄送人、密送人input框顯示
$('.chao').click(function(){
$('.input-chao').css('display','block');
$('.chao').css('display','none');
})
//抄送人、密送人input框顯示
$('.mi').click(function(){
$('.input-mi').css('display','block');
$('.mi').css('display','none');
})
});
</script>
</body>
</html>