thinkphp 网站内容自动邮件群发插件,ajax触发

一,要求:
总体要求:后台提前输入发信人,收信人.每天自动抽取本网站的部分内容,自动给邮箱群发邮件.

1,每天限制发送时间段,减轻服务器负担
2,网站首页被访客访问时ajax自动触发,每天限制自动触发三次
3,检测发信账号发送次数是否超过每日限制,一天不要超过8条,否则可能会进收件人的垃圾箱
4,判断收信人,多久前被群发过,一般限制2周收一次
5,循环发送并判断收信人是否已退订
6,发信内容,发信标题,增加随机排序,多标题随机抽取.
7,后台可增加多个发信人邮箱.轮流发送,防止被拉黑
8,增加手动发送.测试预览功能等.
9,后台可批量插入邮件列表
10,依赖PHPMailer插件
11,发送统计充分利用txt文件记录,提高速度

二,后台截图

在这里插入图片描述

在这里插入图片描述
三,数据库建立表格,前缀自己修改

CREATE TABLE `tg_sendemail` (
  `id` int(11) NOT NULL,
    `open` int(1) DEFAULT 1  COMMENT '是否开否邮件群发功能',

  `send_email` varchar(555) DEFAULT NULL COMMENT '发信邮箱列表 填多个,则轮流发送邮件',
  `least_days` int(11) DEFAULT 7 COMMENT '收信人收信周期,填7,表示他7天内最多只能收到一个邮件',
  `max_send_rows` varchar(255) DEFAULT 10 COMMENT '每个邮箱每天最多发给别人几条,一般不要超过10条',
  `goods_rows` int(11) DEFAULT 9  COMMENT '发信内容中包含商品条数',
  `goods_catid` varchar(255) DEFAULT '' COMMENT '发信中商品所属分类编号ID,填0表示不限制分类,多个分类用英文逗号隔开',
`sendemailtitle` varchar(999) DEFAULT NULL COMMENT '邮件标题,一行一个',
`title` varchar(255) DEFAULT NULL COMMENT '模板页面logo下面的主标题',
`subtitle` varchar(555) DEFAULT NULL COMMENT '模板页面副标题',
  `can_cancel` int(11) DEFAULT 1  COMMENT '是否开启退订功能.用户点击退订后,我们网站将不再给该用户发信'
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

ALTER TABLE `tg_sendemail`
  ADD PRIMARY KEY (`id`);
INSERT INTO `xiaoxiao`.`tg_sendemail` (
`id` ,
`open`,
`send_email` ,`least_days` ,`max_send_rows` ,`goods_rows` ,`goods_catid`
 ,`sendemailtitle` ,`title` ,`subtitle` ,`can_cancel`)
VALUES (
'1', '1',NULL , '7', '10', '9', '0',  NULL ,NULL , NULL , '1'
);
CREATE TABLE `tg_sendemail_list` (
  `id` int(11) NOT NULL,
  `email` varchar(255) DEFAULT NULL ,
  `is_cancel` int(11) DEFAULT 0 COMMENT '是否退订',
  `last_time` int(11) DEFAULT 0  COMMENT '上次收信时间',
   `counts` int(11) DEFAULT 0 COMMENT '总收信次数'
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
ALTER TABLE `tg_sendemail_list`
  ADD PRIMARY KEY (`id`);
  ALTER TABLE `tg_sendemail_list`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=1;

/Runtime/目录中的统计文件.可能需要手工建立.注意,不要清空缓存时,删除掉了.
sendemail2.txt
sendemail_record.txt
success_sendemail_times.txt

四,后台模板参考

 <div class="with-padding">
        <form id="form" action="{:U('dosendemail')}" method="post" class="form-horizontal" enctype="multipart/form-data">
    <div class="container-fluid ">
 <div class="col-md-6">		
			       <div class="form-item cf">
                <label class="item-label">是否开启邮件群发功能<span class="check-tips"></span></label>
                <div class="controls">
                    <select class="form-control form-input-width"  name="open">
                        <option value="1" <if condition="$cont['open'] eq 1 ">selected="selected"</if>>选中表示已开启</option>				
						<option value="0" <if condition="$cont['open'] eq 0 ">selected="selected"</if>>选中表示已关闭</option>
                    </select>
                </div>
            </div>
     <div class="form-item cf">
                <label class="item-label">发信邮箱列表,填多个,则轮流发送邮件,一行一个,格式为:<br> 123@qq.com|kkyfzvwi|smtp.qq.com<br> ,前面为邮箱,中间为授权码或密码,最后为smtp服务器
				<br> 
				<a target="_blank"href="https://service.mail.qq.com/cgi-bin/help?subtype=1&&no=1001256&&id=28">查看什么是授权码</a><br/>		
					<a target="_blank" href="https://service.mail.qq.com/cgi-bin/help?subtype=1&&no=166&&id=28">查看怎么开通smtp,一般在邮箱右上角,设置,账号设置,或常规设置中开通</a><br/>		
				</label>
                <div class="controls">
                    <label class="textarea input-large "><textarea name="send_email"class=" form-control form-text-area-size"rows='10'>{$cont.send_email}</textarea></label>
                </div>
            </div>
            <div class="form-item cf">
                <label class="item-label">收信人收信周期,7,表示他7天内最多只能收到一个邮件<span class="check-tips"></span></label>
                <div class="controls">
                    <input type="text" class="text input-large form-control form-input-width" name="least_days"
                           value="{$cont.least_days}">
                </div>
            </div>    
		   <div class="form-item cf">
                <label class="item-label">每个邮箱每天最多发给别人几条,一般不要超过10<span class="check-tips"></span></label>
                <div class="controls">
                    <input type="text" class="text input-large form-control form-input-width" name="max_send_rows"
                           value="{$cont.max_send_rows}">
                </div>
            </div>
			<div class="form-item cf">
                <label class="item-label">发送的邮件标题,一行填一个,随机选取<span class="check-tips"></span></label>
                <div class="controls">			   
						   <textarea name="sendemailtitle"class=" form-control form-text-area-size"rows='10'>{$cont.sendemailtitle}</textarea>				   
                </div>
            </div>
				
			<div class="form-item cf">
                <label class="item-label">发信内容中包含商品条数<span class="check-tips"></span></label>
                <div class="controls">
                    <input type="text" class="text input-large form-control form-input-width" name="goods_rows"
                           value="{$cont.goods_rows}">
                </div>
            </div>	
			<div class="form-item cf">
                <label class="item-label">模板页面logo下面的主标题<span class="check-tips"></span></label>
                <div class="controls">
                    <input type="text" class="text input-large form-control form-input-width" name="title"
                           value="{$cont.title}">
                </div>
            </div>	
			<div class="form-item cf">
                <label class="item-label">模板页面副标题<span class="check-tips"></span></label>
                <div class="controls">			
				<textarea name="subtitle"class=" form-control form-text-area-size"rows='3'>{$cont.subtitle}</textarea>		
                </div>
            </div>	
			<div class="form-item cf">
                <label class="item-label">发信中商品所属分类编号ID,0表示不限制分类,如果填多个分类,则用|隔开,不限制分类的层级,所以,可以同时填二级分类及三级分类.比如:<br/><font color=red>113|654|674</font><br/> 默认会发送这些分类下,每个小分类的一条最新商品,小分类的数目如果超出.会随机选取其中的一些分类.<span class="check-tips"></span></label>
                <div class="controls">
                    <input type="text" class="text input-large form-control form-input-width" name="goods_catid"
                           value="{$cont.goods_catid}">
                </div>
            </div>
	           <div class="form-item cf">
                <label class="item-label">是否开启退订功能.用户点击退订后,我们网站将不再给该用户发信<span class="check-tips"></span></label>
                <div class="controls">
                    <select class="form-control form-input-width"  name="can_cancel">
                        <option value="1" <if condition="$cont['can_cancel'] eq 1 ">selected="selected"</if>>用户可退订</option>		
						<option value="0" <if condition="$cont['can_cancel'] eq 0 ">selected="selected"</if>>用户不可退订</option>       
                    </select>
                </div>
            </div>  
				<div class="form-item cf">
                <label class="item-label">上次完成情况及时间<span class="check-tips"></span></label>
                <div class="controls">
                    <font color=green><?php $cache3=RUNTIME_PATH.'sendemail_record.txt';echo file_get_contents($cache3);?></font>
                </div>
            </div>	
		</div>
			 <div class="col-md-6">
     <div class="form-item cf">
                <label class="item-label">收信邮箱列表,一行一个,保存后,会自动插入数据库<span class="check-tips"></span></label>
                <div class="controls">
                    <label class="textarea input-large "><textarea name="get_email"class=" form-control form-text-area-size"rows='28'></textarea></label>
                </div>
            </div>		
  </div> </div> <div class="clearfix"></div>
            <hr>
            <div class="form-item">
                <input type="hidden" name="id" value="{$cont.id}"/>
				
                <button type="submit" class="btn submit-btn ajax-post2" target-form="form-horizontal">保存</button>&nbsp;&nbsp;	&nbsp;<a href="/?a=sendemail&test=1"target="_blank"style="border:1px solid red;font-size:16px;pading:9px;display:inline-block;color:red">发送前预览 (不会发送)</a>
							&nbsp;&nbsp;	&nbsp;<a href="/?a=sendemail"target="_blank"style="border:1px solid red;font-size:16px;pading:9px;display:inline-block;color:blue">手工发送 (默认每天自动发送)</a>
<br/><br/><br/>
            </div>
        </form>
    </div>

五,后台控制器参考


  public function sendemail_list(){
       $list = $this->lists('sendemail_list', $map, 'id desc');
       $this->assign('list', $list);
       $this->assign('lanmu', '邮件群发列表');
       $this->display();
    }
	
	   public function sendemail_list_edit(){
        if(I('id')){
            $id=I('id');
            $cont=M('sendemail_list')->where('id='.$id)->find();
            $this->assign('cont', $cont);
        }
        $this->assign('lanmu', '添加/编辑列表');
        $this->display();  
    }

public function dosendemail(){
        if(I('id')){
            $id=I('id');
			if(I('get_email')!==''){
				$pws = explode("\r\n", I('get_email'));
				//print_r($pws);exit;
foreach($pws as $pw){
	$where['email']=$pw;
	   $cont=M('sendemail_list')->where($where)->find();
	   if(!$cont){
		   $arr=array();
	$arr['email']=$pw;
	$id2=M('sendemail_list')->add($arr);
	   }

}
	}
			$arr2=array();
		//	print_r(I());exit;
			$arr2['send_email']= I('send_email');
			$arr2['least_days']= I('least_days');
			$arr2['max_send_rows']= I('max_send_rows');
			$arr2['goods_rows']= I('goods_rows');
			$arr2['goods_catid']= I('goods_catid');
			$arr2['can_cancel']= I('can_cancel');
			$arr2['title']= I('title');
				$arr2['open']= I('open');
			$arr2['subtitle']= I('subtitle');
		$arr2['sendemailtitle']= I('sendemailtitle');
			//unset($arr2('get_email'));
            $cont=M('sendemail')->where('id=1')->save($arr2);
		$cache1=RUNTIME_PATH.'sendemail.txt';
		$oldstr=file_put_contents($cache1,'');//更新缓存
	//	var_dump($cont);exit;
            if ($cont||$id2) {
			
                $this->success('修改成功!',U('sendemail'));
            } else {
                $this->error('修改可能没生效,请刷新核实!');
            }
        }
       
    }

六,前台相关自定义函数,需要下载PHPMailer插件,thinkphp3的插件保存在\ThinkPHP\Library\Vendor\PHPMailer,自己查看是否已下载

function sendMail2($to, $title, $content,$username,$pswd,$host) {
    Vendor('PHPMailer.PHPMailerAutoload');
    $mail = new PHPMailer(); //实例化
    $mail->IsSMTP(); // 启用SMTP
	
//$mail->SMTPDebug = 1;//是否开启调试模式

    $mail->Host=$host; //smtp服务器的名称(这里以QQ邮箱为例)
    $mail->SMTPAuth = C('MAIL_SMTPAUTH'); //启用smtp认证
    $mail->Username = $username; //你的邮箱名
    $mail->Password = $pswd; //邮箱密码
    $mail->From =$username; //发件人地址(也就是你的邮箱地址)
    $mail->FromName = C('MAIL_FROMNAME'); //发件人姓名 //统一的发信人姓名,自己定义
    $mail->AddAddress($to,"尊敬的客户");
    $mail->WordWrap = 650; //设置每行字符长度
    $mail->IsHTML(C('MAIL_ISHTML')); // 是否HTML格式邮件
    $mail->CharSet=C('MAIL_CHARSET'); //设置邮件编码
    $mail->Subject =$title; //邮件主题
    $mail->Body = $content; //邮件内容
    $mail->AltBody = "这是一个纯文本的身体在非营利的HTML电子邮件客户端"; //邮件正文不支持HTML的备用显示
    $mail->SMTPSecure = 'ssl';
	$mail->Port = 465;
	$ss=$mail->Send ();
	//var_dump($ss);exit;
	if (!$ss ) {
return $mail->ErrorInfo;
}else{
	return($ss);
}   
}

七.前台控制器.取消订阅邮件

    function cancel_email(){
	 $email=I('email');
	// print_r($email);exit;

	 $s=M('sendemail_list')->where('email="'.$email.'"')->save(array('is_cancel'=>1 ));
	 
	  $this->success('提交成功',"index.php");
 }

八,前台核心控制器

   
function sendemail() {
	/**
	 1,每天限制发送时间段,减轻服务器负担
	 2,每天限制自动触发三次
	 3,再检测发信账号是否发送次数超限
	 4,再判断收信人,多久前被群发过,限制一周收一次
	 5,循环发送并判断收信人是否退订
	 6,发信内容,发信标题,增加随机变量
	 **/
	$cache2=RUNTIME_PATH.'success_sendemail_times.txt';
	$time = (date("H"));
	if(!I('test')) {
		$old_success_sendemail_times=unserialize(file_get_contents($cache2));
		if(!$old_success_sendemail_times) {
			file_put_contents($cache2,serialize(array(date("Ymd"),0)));
			$old_success_sendemail_times=unserialize(file_get_contents($cache2));
		}
		//如果日期相同,则先加一
		if($old_success_sendemail_times[0]== date("Ymd") ) {
			$old_success_sendemail_times[1]=$old_success_sendemail_times[1]+1;
			file_put_contents($cache2,serialize($old_success_sendemail_times));
			//print_r($old_success_sendemail_times);exit;
			if( $old_success_sendemail_times[1] >100 ) {
				exit('触发邮件群发功能不得超过100次');
			}
		} else {
			file_put_contents($cache2,serialize(array(date("Ymd"),0)));
		}
		if ($time !="09" && $time!= "13" ) {
			//规定的时间段才会触发9点几分或13点几分时才能发送
			exit('循环发送时间段不在合法范围内,早上9:00-9:59及下午13:00-13:59之间为合法时间段');
		}
	}
	header("Content-Type:text/html; charset=utf-8");
	$con=M('sendemail')->where('id=1')->find();
	if($con['open'] ==0) {
		exit('群发功能已被主动关闭');
	}
	$cache3=RUNTIME_PATH.'sendemail_record.txt';
	$mytime=time()-$con['least_days']*3600*24;
	//print_r($mytime);exit;
	//用户可退订
	if($con['can_cancel']==1) {
		$listm=M('sendemail_list')->where('is_cancel=0 and last_time <'.$mytime)->select();
	} else {
		//查询可收信的账号
		$listm=M('sendemail_list')->where(' last_time <'.$mytime)->select();
	}
	if( I('test') or $con['least_days']==0 ) {
		$listm=M('sendemail_list')->select();
	}
	//var_dump($listm);exit;
	//发信
	if(!I('test')) {
		if(!$listm) {
			//账号都超限,入日志
			$times='<font color=red>'.date('Y/m/d H:i:s').' 发信失败,所有收信账号'.$con['least_days'].'日内,收信数量超过1条.</font><br/>';
			$record=file_get_contents($cache3);
			//var_dump($record);exit;
			$record=substr($record,0,40000);
			file_put_contents($cache3,$times.$record);
		}
	}
	//print_r(99);exit;
	//发信标题
	$sendemailtitle=explode ( "\r\n",$con['sendemailtitle']);
	//查询商品开始 goods_catid goods_rows条数
	$goods_rows=$con['goods_rows'];
	$arr91=[];
	$arr8='';
	if($con['goods_catid']==0 || $con['goods_catid']==5 ) {
		$arr91=xiaji_arr2('conttype',5);
	} else {
		$arr6=explode ( "|",trim($con['goods_catid']));
		foreach($arr6 as $k7 => $arr7) {
			//$listt=xiaji('conttype',$arr7);	
			$arr90=xiaji_arr2('conttype',$arr7);
			$arr91=array_merge($arr91,array_values($arr90));
			//$arr8=$k7==0? $listt : ($arr8.','.$listt);
		}
	}
	shuffle($arr91);
	$arr92=array_slice($arr91,0,$goods_rows);
	//print_r($arr92);exit;
	$arr8=implode( ",",$arr92);
	//print_r($arr8);exit;
	$where="  type in ($arr8) ";
	$sql="SELECT MAX(id) as id,title,pic,type FROM `tg_contlist`  where $where group by type  limit $goods_rows ";
	//$cache11=RUNTIME_PATH.'1l.txt';
	//file_put_contents($cache11,$sql);
	$nextlist = M()->query($sql);
	//print_r($nextlist);exit;
	//print_r($sendemailtitle);exit;	
	$str=$str2='';
	$str0='
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>'.$sendemailtitle[array_rand($sendemailtitle)].'</title> </head><body style="margin:0;font-size:14px;"><div style="width:100%;height:100%;background: #a6e9d7;overflow:hidden"> <div style="width:600px;margin:0 auto;list-style:none;overflow:hidden"> <div style="float:left;width:600px;height:400px;text-align:center;background: url(http://www.ld-pd.com/Public/home/images/Destination1.jpg) no-repeat center bottom;background-size:cover; 1padding:20px;"><div style="padding:0px;"><img src="http://www.ld-pd.com/Uploads/img/2021020216_49527222221889762.png"style="width:60%;margin-top:10px;"><p><span style="font-size:22px;font-weight:blod;color:#ec6941;">'.$con['title'].'</span></p><p><span style="font-size:16px;font-weight:blod;line-height:26px;color:#777;">'.$con['subtitle'].'</span></p></div></div><div style="width:600px;margin:0 auto;background: #fff;text-align: center;"> <a style="width:240px;height:50px;margin:0 auto;line-height:50px;text-align: center;display:inline-block;font-size: 18px;margin:40px;text-decoration:none;background-color: rgb(243, 156, 18);color:#fff;"href="http://www.ld-pd.com/"> View More </a></div><div style="width:600px;margin:0 auto;background: #fff;text-align: center;;overflow:hidden;"> ';
	//======================================
	//大循环开始
	//======================================
	//收信人
	foreach($listm as $arr) {
		$str='';
		$str3='';
		//循环9个商品
		shuffle($nextlist);
		//随机商品排序
		foreach($nextlist as $arr9) {
			$str.='<a style="float:left;width:258px;box-shadow: 2px 2px 6px #999;border-top:1px solid #eee;border-left:1px solid #eee;height:auto;text-align:center;;overflow:hidden;margin:20px"href="http://www.ld-pd.com/?a=cpinfo&id='.$arr9['id'].'"> <img src="http://www.ld-pd.com/'.$arr9['pic'].'"style="width:260px;height:187px;margin-bottom:0;"><span style="display:inline-block;width:240px;line-height:27px;height:49px;text-align:center;;background-color: rgb(241, 241, 241);color:#333;overflow:hidden;padding:10px;font-size:14px;">'.$arr9['title'].'</span></a>';
		}
		$str2='</div><div style="width:600px;margin:0 auto;background: #fff;text-align: center;"> <a style="width:240px;height:50px;margin:0 auto;line-height:50px;text-align: center;display:inline-block;font-size: 18px;margin:40px;text-decoration:none;background-color: rgb(243, 156, 18);color:#fff;"href="http://www.ld-pd.com/"> View More </a></div><div style="width:600px;margin:0 auto;background: rgb(31, 200, 153);text-align: center;color:#fff;overflow:hidden"> <div style="width:200px;margin:0 auto;background: rgb(31, 200, 153);text-align: center;float:left;padding:20px 0"> <br><img src="http://www.ld-pd.com/Uploads/img/2021020216_49527222221889762.png"style="width:100px;margin-top:10px;display:inline-block;"></div><div style="width:400px;margin:0 auto;background: rgb(31, 200, 153);text-align: left;;float:left;padding:20px 0">Contact us:<br>Add : 288 Woodlands Loop #04-00, Singapore 738100<br>Tel : (+65)31588759<br>Fax : (+65)31588700<br>Email : info@ld-pd.com <br><br><a style="text-decoration:none;color:#777;"href="http://http://www.ld-pd.com/?a=cancel_email&email='.$arr['email'].'">Unsubscribe from this email? click here!</a></div></div></div></div> </body> </html>';
		$str3=$str0.$str.$str2;
		if(I('test')) {
			echo $str3;
			exit;
		}
		//判断发信人
		$cache1=RUNTIME_PATH.'sendemail.txt';
		$oldstr=file_get_contents($cache1);
		$arr3=array();
		if(!$oldstr) {
			//print_r($con);exit;
			$arr2=explode ( "\r\n",$con['send_email']);
			//判断邮箱数量与缓存中,是否一致
			// 创建二维数组
			for ($i=0; $i <count($arr2) ; $i++) {
				$arr4=explode ( "|",$arr2[$i]);
				//print_r($arr4);exit;
				$arr3[$i][]=0;
				//发信条数,一天不超10条.如果条数大于后台的值,则更新为0 
				$arr3[$i][]=$arr4[1];
				//授权密码
				$arr3[$i][]=date("Ymd");
				//发1-10封信循环,开始的日期
				$arr3[$i][]=$arr4[0];
				//账号
				$arr3[$i][]=$arr4[2];
				//smtp服务器
			}
			$oldstr=serialize($arr3);
			file_put_contents($cache1,$oldstr);
		}
		$old_arr2=unserialize($oldstr);
		//循环发信账号,依次发送
		$cont1=0;
		foreach($old_arr2 as $k5=>$arr5  ) {
			//
			//如果今天是第二天,先重置上一天的发送次数为0
			if($arr5[2]!=date("Ymd")) {
				$old_arr2[$k5][2]=date("Ymd");
				$old_arr2[$k5][0]=0;
				file_put_contents($cache1,serialize($old_arr2));
			}
		}
		//print_r( $old_arr2);exit;
		foreach($old_arr2 as $k5=>$arr5  ) {
			//判断有没有超过条数,一天内
			if( $arr5[0]>= $con['max_send_rows'] ) {
				//账号都超限,入日志
				$times='<font color=blue>'.date('Y/m/d H:i:s').' 发信失败,发信账号 '.$arr5['3'].' 今日次数超限.</font><br/>';
				$record=file_get_contents($cache3);
				$record=substr($record,0,40000);
				file_put_contents($cache3,$times.$record);
				continue;
			} else {
				//print_r($k5.'---');
				//print_r($arr);exit;
				$cont1++;
				//遍历收信邮箱进行发信	
				$send=sendMail2($arr['email'], $sendemailtitle[array_rand($sendemailtitle)],$str3,$arr5['3'] ,$arr5['1'],$arr5['4']   );
				//print_r($send);exit;
				if($send==1) {
					//写入邮件记录的缓存 发信人条数加一,
					$old_arr2[$k5][0]++;
					///记录发信人的发信次数
					file_put_contents($cache1,serialize($old_arr2));
					M('sendemail_list')->where('email="'.$arr['email'].'"')->setInc('counts',1);
					M('sendemail_list')->where('email="'.$arr['email'].'"')->save(array('last_time'=>time()));
					//判断发信账号是否今天超过条数,
					$times=date('Y/m/d H:i:s').' 发信成功,发信人:'.$arr5['3'].',收信人:'.$arr['email'].'<br/>';
					$record=file_get_contents($cache3);
					$record=substr($record,0,40000);
					file_put_contents($cache3,$times.$record);
					//发信成功或失败日志
					break;
					//发信成功一次后.则跳出发信人循环,进入上层收信人循环体中.
				} else {
					//如果失败,则写入失败原因.这里不更新数据库
					$old_arr2[$k5][0]++;
					///记录发信人的发信次数
					file_put_contents($cache1,serialize($old_arr2));
					$times=date('Y/m/d H:i:s').' 失败,发:'.$arr5['3'].',收:'.$arr['email'].'<br/>异常:'.$send;
					$record=file_get_contents($cache3);
					$record=substr($record,0,4000000);
					file_put_contents($cache3,$times.$record);
					//发信成功或失败日志
					break;
					//发信一次后.则跳出发信人循环,进入上层收信人循环体中.
				}
			}
			//今日发信超限则直接跳过
		}
		//判断发信人结束	
		if($cont1==0) {
			//账号都超限,入日志
			$times='<font color=gray>'.date('Y/m/d H:i:s').' 发信失败,所有发信账号今日次数超限.</font><br/>';
			$record=file_get_contents($cache3);
			$record=substr($record,0,40000);
			file_put_contents($cache3,$times.$record);
			break;
		}
	}
	//print_r($old_arr2);exit;
	exit('可能已发送完成,请进收件箱查看或请进后台刷新查看今日发送日志');
}
	

九,前台模板,ajax触发发器

<script type="text/javascript">
	    $.post("{:U('sendemail')}");
	  </script>  

十.以下是手工群发功能的代码.是在以上代码基础上修改的.只供参考
需要后台点击群发.内容图片等.需要后台自定义.
这里只贴出核心代码.

function sendemail2() {
	$cache2=RUNTIME_PATH.'success_sendemail2_times.txt';
	$time = (date("H"));
	if(!I('test')) {
		$old_success_sendemail_times=unserialize(file_get_contents($cache2));
		if(!$old_success_sendemail_times) {
			file_put_contents($cache2,serialize(array(date("Ymd"),0)));
			$old_success_sendemail_times=unserialize(file_get_contents($cache2));
		}
		//如果日期相同,则先加一
		if($old_success_sendemail_times[0]== date("Ymd") ) {
			$old_success_sendemail_times[1]=$old_success_sendemail_times[1]+1;
			file_put_contents($cache2,serialize($old_success_sendemail_times));
			//print_r($old_success_sendemail_times);exit;
			if( $old_success_sendemail_times[1] >100 ) {
				exit('触发邮件群发功能不得超过100次');
			}
		} else {
			file_put_contents($cache2,serialize(array(date("Ymd"),0)));
		}
	}
	header("Content-Type:text/html; charset=utf-8");
	$con=M('sendemail')->where('id=2')->find();
	$cache3=RUNTIME_PATH.'sendemail2_record.txt';
	$mytime=time()-$con['least_days']*3600*24;
	//print_r($mytime);exit;
	//查询可收信的账号
	$listm=M('sendemail2_list')->where(' last_time <'.$mytime)->select();
	if( I('test') or $con['least_days']==0 ) {
		$listm=M('sendemail2_list')->select();
	}
	//var_dump($listm);exit;
	//发信
	if(!I('test')) {
		if(!$listm) {
			//账号都超限,入日志
			$times='<font color=red>'.date('Y/m/d H:i:s').' 失败,所有收信账号'.$con['least_days'].'日内,收信数量超过1条.</font><br/>';
			$record=file_get_contents($cache3);
			//var_dump($record);exit;
			$record=substr($record,0,4000000);
			file_put_contents($cache3,$times.$record);
		}
	}
	//print_r(99);exit;
	//发信标题
	$sendemailtitle=explode ( "\r\n",$con['sendemailtitle']);
	$str=$str2='';
	$str0='<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>'.$sendemailtitle[array_rand($sendemailtitle)].'</title><style>.ldpd1{width:600px;}.ldpd2,.ldpd4{width:45%;;max-width:270px}.ldpd3{width:45%;;max-width:270px}@media screen and (max-width: 768px){.ldpd1{width:100%;max-width:600px}.ldpd2{width:90%;;max-width:540px}.ldpd3{width:95%;;max-width:570px}.ldpd4{width:70%;;max-width:420px}}</style></head><body style="margin:0;font-size:14px;color:#23496d;font-family:Arial,sans-serif,-apple-system,BlinkMacSystemFont;"><div style="width:100%;height:100%;background: #9c9e9f;overflow:hidden;"><div style="list-style:none;overflow:hidden;background: #fff;;max-width:600px"class="ldpd1"><div style="float:left;;max-width:600px"class="ldpd1"><a  href="http://www.ld-pd.com/"><img src="'.$con['logo'].'" style="width:40%;margin-top:10px;;max-width:200px"></a><a  href="'.$con['banner_url'].'"><img src="'.$con['banner'].'" style="width:100%;margin-top:10px;;max-width:600px"></a><div style="padding:15px;text-align:left;color:#23496d;;max-width:600px;line-height:30px;"><span style="font-size:22px;font-weight:blod;">'.$con['des_title'].'</span><br/><span style="font-size:16px;line-height:24px">'.$con['des'].'</span><br/><a style="font-size: 16px;line-height:34px;text-decoration:none;color:#00a4bd;" href="'.$con['skip1url'].'">'.$con['skip1title'].'</a><div style="border-bottom:1px solid gray;;max-width:600px;height:1px;margin:20px 0;"class="ldpd1"></div></div></div>';
	//======================================
	//大循环开始
	//======================================
	//收信人
	foreach($listm as $arr) {
		$str='';
		$str3='';
		$str2='';
		//主体内容
		if($con['pic1']) {
			$str.='	<div style="margin:0 auto;background: #fff;padding-bottom:20px;overflow:hidden;max-width:600px;"class="ldpd1">
				<a style="float:left;height:auto;margin:0 15px"class="ldpd4" href="'.$con['url1'].'">
				<img src="'.$con['pic1'].'" style="width:100%;;max-width:600px;height:auto;;"></a>
				<div style="float:left;padding-left: 20px;max-width:270px;"class="ldpd3">
					<span style="font-size:21px;font-weight:blod;line-height:32px;margin-bottom:20px">'.$con['title1'].'</span><br/>
					<span style="font-size:16px;line-height:26px">'.$con['description1'].' </span>
					<br/>
					<a style="font-size: 16px;line-height:34px;text-decoration:none;color:#00a4bd;" href="'.$con['url1'].'">Read more click here!</a>
				</div>
			</div>';
		}
		if($con['pic2']) {
			$str.='	<div style="margin:0 auto;;max-width:600px;background: #fff;padding-bottom:20px;overflow:hidden"class="ldpd1">
				<a style="float:left;height:auto;margin:0 15px" href="'.$con['url2'].'"class="ldpd4">
				<img src="'.$con['pic2'].'" style="width:100%;;max-width:600px;;height:auto;;"></a>
				<div style="float:left;;max-width:270px;padding-left: 20px"class="ldpd3">
					<span style="font-size:21px;font-weight:blod;line-height:32px;margin-bottom:20px">'.$con['title2'].'</span><br/>
					<span style="font-size:16px;line-height:26px">'.$con['description2'].' </span>
					<br/>
					<a style="font-size: 16px;line-height:34px;text-decoration:none;color:#00a4bd;" href="'.$con['url2'].'">Read more click here!</a>
				</div>
			</div>';
		}
		if($con['pic3']) {
			$str.='	<div style="margin:0 auto;background: #fff;padding-bottom:20px;overflow:hidden"class="ldpd1">
				<a style="float:left;height:auto;margin:0 15px" href="'.$con['url3'].'"class="ldpd4">
				<img src="'.$con['pic3'].'" style="width:100%;;;max-width:600px;height:auto;;"></a>
				<div style="float:left;padding-left: 20px"class="ldpd3">
					<span style="font-size:21px;font-weight:blod;line-height:32px;margin-bottom:20px">'.$con['title3'].'</span><br/>
					<span style="font-size:16px;line-height:26px">'.$con['description3'].' </span>
					<br/>
					<a style="font-size: 16px;line-height:34px;text-decoration:none;color:#00a4bd;" href="'.$con['url3'].'">Read more click here!</a>
				</div>
			</div>';
		}
		if($con['pic4']) {
			$str.='	<div style="margin:0 auto;background: #fff;padding-bottom:20px;overflow:hidden"class="ldpd1">
				<a style="float:left;height:auto;margin:0 15px" href="'.$con['url4'].'"class="ldpd2">
				<img src="'.$con['pic4'].'" style="height:auto;width:100%;;max-width:600px;;"></a>
				<div style="float:left;padding-left: 20px"class="ldpd3">
					<span style="font-size:24px;font-weight:blod;line-height:32px;margin-bottom:20px">'.$con['title4'].'</span><br/>
					<span style="font-size:16px;line-height:26px">'.$con['description4'].' </span>
					<br/>
					<a style="font-size: 16px;line-height:34px;text-decoration:none;color:#00a4bd;" href="'.$con['url4'].'">Read more click here!</a>
				</div>
			</div>';
		}
		if($con['footer2title']) {
			$css='style="width:auto;height:90px;;"';
			$class='class="ldpd1"';
		} else {
			$css='style="height:auto;width:100%;"';
			$class='class="ldpd6"';
		}
		$str2='	<div style="margin:0 auto;background: #fff;padding:20px;padding-top:0px;"><div style="border-bottom:1px solid gray;height:1px;margin-bottom:20px;;max-width:600px;"class="ldpd1"></div>
			<a style="font-size: 20px;font-weight:888;line-height:34px;text-decoration:none;color:#23496d;" href="'.$con['skip2url'].'">'.$con['skip2title'].'</a><br/>
			</div>
			<div style="margin:0 auto;;max-width:600px;background: #fff;padding:20px;width:100%".class="ldpd1">
			<div style="float:left;height:auto;padding:10px;padding-bottom:50px;width:90%".class="ldpd2">
				<a href="'.$con['footer1url'].'">
				<img style=";max-width:600px;width:100%"src="'.$con['footer1pic'].'" '.$css.'></a><br/><br/>
				<a style="font-size: 22px;line-height:34px;text-decoration:none;color:#00a4bd;" href="'.$con['footer1url'].'">'.$con['footer1title'].'</a><br/><br/>
					<span style="font-size:16px;line-height:26px">'.$con['footer1des'].' </span>
				</div></div>
		<p style="padding:0 40px;;max-width:600px;margin-bottom:20px;text-align:center;color:#555;font-size:12px; 1px">Add :  288 Woodlands Loop #04-00, Singapore 738100 Email :  info@ld-pd.com  Tel : (+65)31638599   Fax :  (+65)31588700<br/></p>
		</div>
	</div>
</body>
</html>';
		$str3=$str0.$str.$str2;
		if(I('test')) {
			echo $str3;
			exit;
		}
		//判断发信人
		$cache1=RUNTIME_PATH.'sendemail2.txt';
		$oldstr=file_get_contents($cache1);
		$arr3=array();
		if(!$oldstr) {
			//print_r($con);exit;
			$arr2=explode ( "\r\n",$con['send_email']);
			//判断邮箱数量与缓存中,是否一致
			// 创建二维数组
			for ($i=0; $i <count($arr2) ; $i++) {
				$arr4=explode ( "|",$arr2[$i]);
				//print_r($arr4);exit;
				$arr3[$i][]=0;
				//发信条数,一天不超10条.如果条数大于后台的值,则更新为0 
				$arr3[$i][]=$arr4[1];
				//授权密码
				$arr3[$i][]=date("Ymd");
				//发1-10封信循环,开始的日期
				$arr3[$i][]=$arr4[0];
				//账号
				$arr3[$i][]=$arr4[2];
				//smtp服务器
			}
			$oldstr=serialize($arr3);
			file_put_contents($cache1,$oldstr);
		}
		$old_arr2=unserialize($oldstr);
		//循环发信账号,依次发送
		$cont1=0;
		foreach($old_arr2 as $k5=>$arr5  ) {
			//如果今天是第二天,先重置上一天的发送次数为0
			if($arr5[2]!=date("Ymd")) {
				$old_arr2[$k5][2]=date("Ymd");
				$old_arr2[$k5][0]=0;
				file_put_contents($cache1,serialize($old_arr2));
			}
		}
		//print_r( $old_arr2);exit;
		foreach($old_arr2 as $k5=>$arr5  ) {
			//判断有没有超过条数,一天内
			if( $arr5[0]>= $con['max_send_rows'] ) {
				//账号都超限,入日志
				$times='<font color=blue>'.date('Y/m/d H:i:s').' 失败,发号 '.$arr5['3'].' 次数超</font><br/>';
				$record=file_get_contents($cache3);
				$record=substr($record,0,4000000);
				file_put_contents($cache3,$times.$record);
				continue;
			} else {
				//print_r($k5.'---');
				//print_r($arr);exit;
				$cont1++;
				//遍历收信邮箱进行发信	
				$send=sendMail2($arr['email'], $sendemailtitle[array_rand($sendemailtitle)],$str3,$arr5['3'] ,$arr5['1'],$arr5['4']   );
				//print_r($send);exit;
				if($send==1) {
					//写入邮件记录的缓存 发信人条数加一,
					$old_arr2[$k5][0]++;
					///记录发信人的发信次数
					file_put_contents($cache1,serialize($old_arr2));
					M('sendemail2_list')->where('email="'.$arr['email'].'"')->setInc('counts',1);
					M('sendemail2_list')->where('email="'.$arr['email'].'"')->save(array('last_time'=>time()));
					//判断发信账号是否今天超过条数,
					$times=date('Y/m/d H:i:s').' 成功,发:'.$arr5['3'].',收:'.$arr['email'].'<br/>';
					$record=file_get_contents($cache3);
					$record=substr($record,0,4000000);
					file_put_contents($cache3,$times.$record);
					//发信成功或失败日志
					break;
					//发信成功一次后.则跳出发信人循环,进入上层收信人循环体中.
				} else {
					//写入邮件记录的缓存 发信人条数加一,
					$old_arr2[$k5][0]++;
					///记录发信人的发信次数
					file_put_contents($cache1,serialize($old_arr2));
					$times=date('Y/m/d H:i:s').' 失败,发:'.$arr5['3'].',收:'.$arr['email'].'<br/>异常:'.$send;
					$record=file_get_contents($cache3);
					$record=substr($record,0,4000000);
					file_put_contents($cache3,$times.$record);
					//发信成功或失败日志
					break;
					//发信一次后.则跳出发信人循环,进入上层收信人循环体中.
				}
			}
			//今日发信超限则直接跳过
		}
		//判断发信人结束	
		if($cont1==0) {
			//账号都超限,入日志
			$times='<font color=#000000>'.date('Y/m/d H:i:s').' 失败,所有发号今次超</font><br/>';
			$record=file_get_contents($cache3);
			$record=substr($record,0,4000000);
			file_put_contents($cache3,$times.$record);
			break;
		}
	}
	//print_r($old_arr2);exit;
	exit('可能已发送完成或失败,请进收件箱查看或请进后台刷新查看今日发送日志');
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值