php+mysql 模拟队列发送邮件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了php+mysql 模拟队列发送邮件相关的知识,希望对你有一定的参考价值。

1.使用场景

主要解决php开发过程中,常见的发送多封邮件时页面卡死的问题,如果需要给网站所有用户发送一封系统通知邮件,假设网站有10000个注册用户,发送每封邮件需要0.1秒,直接发送导致页面耗时长卡死,因此就要用到队列的知识.

2.建表语句

create table users (
         user_id int(5) not null auto_increment,
         user_email varchar(40) not null,
         user_password char(32) not null,
         primary key(user_id)
 )engine=myisam default charset=utf8;

create table task_list (
    task_id int(5) not null auto_increment,
    user_email varchar(40) not null,
    status int(2) not null,
    create_time datetime not null,
    update_time datetime not null,
    primary key(task_id)
)engine=myisam default charset utf8;

3.文件结构

技术分享

4.send.php代码(send.php主要是php+mysql模拟队列发送邮件,直接运行该文件页面刷新按钮会一直转,直到程序执行结束)

 1 <?php 
 2 //引入类
 3 $rootPath = dirname(__FILE__);
 4 require $rootPath.‘/PHPMailer/class.phpmailer.php‘;
 5 require $rootPath.‘/PHPMailer/class.smtp.php‘;
 6 
 7 function sendMail($toEmail, $toName) {
 8     global $rootPath;
 9     //实例化类
10     $mail = new PHPMailer;
11 
12     $mail->isSMTP();                                          // Set mailer to use SMTP
13     $mail->Host = ‘smtp.163.com‘;                             // Specify main and backup SMTP servers
14     $mail->SMTPAuth = true;                                   // Enable SMTP authentication
15     $mail->Username = ‘[email protected]‘;                  // SMTP username
16     $mail->Password = ‘‘;                                     // SMTP password
17     $mail->CharSet = ‘UTF-8‘;
18 
19     $mail->setFrom(‘[email protected]‘, ‘163‘);
20     $mail->addAddress($toEmail, $toName);                     
21     $mail->addReplyTo(‘[email protected]‘, ‘163‘);
22 
23     $mail->ishtml(true);                                      // Set email format to HTML
24 
25     $mail->Subject = ‘主题‘;
26     $mail->msgHTML(file_get_contents($rootPath.‘/content.html‘));
27     return $mail->send();    
28 }
29 
30 $link = mysql_connect(‘localhost‘, ‘root‘, ‘root‘);
31 mysql_select_db(‘queue‘);
32 mysql_query(‘set names utf8‘);
33 
34 while(true) {
35     $sql = "SELECT * FROM task_list WHERE status = 0 ORDER BY task_id ASC LIMIT 5";
36     $res = mysql_query($sql);
37     $mailList = array();
38     while($row = mysql_fetch_assoc($res)) {
39         $mailList[] = $row;
40     }
41     
42     if(empty($mailList)) {
43         break;
44     } else {
45         foreach($mailList as $k => $v) {
46             if(sendMail($v[‘user_email‘], ‘qq‘)) {
47                 mysql_query("UPDATE task_list SET status = 1 WHERE task_id = ".$v[‘task_id‘]);
48             }
49             sleep(3);
50         }
51     }
52 }
53 
54 ?>

5.用户注册 ajax异步触发邮件队列(邮件队列会在后台默默执行,不会使前台页面卡死)

流程图

技术分享

reg.php代码

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>注册</title>
 6     <style>    
 7         form{
 8             text-align: center;
 9             padding-top:200px;
10         }
11     </style>
12     <script text="text/javascript" src="jquery.js"></script>
13 </head>
14 <body>
15     <form action="" method="post">
16         <span>邮箱</span><input type="text" name="user_email" /><br /><br />
17         <span>密码</span><input type="password" name="user_password" /><br /><br />
18         <input type="submit" name="reg" value="注册"><br />
19     </form>
20     <?php  
21         if(isset($_POST[‘reg‘])) {
22             $link = mysql_connect(‘localhost‘, ‘root‘, ‘root‘);
23             mysql_select_db(‘queue‘);
24             mysql_query(‘set names utf8‘);
25 
26             $user_email = $_POST[‘user_email‘];
27             $user_password = $_POST[‘user_password‘];
28 
29             $sql = "SELECT * FROM users WHERE user_email = ‘$user_email‘";
30             $res = mysql_query($sql);
31 
32             if(mysql_fetch_row($res)) {
33                 echo "<script>alert(‘用户已经存在‘)</script>";
34             } else {
35                 $sql = "INSERT INTO users(user_email, user_password) VALUES(‘$user_email‘, ‘$user_password‘)";
36                 $res = mysql_query($sql);
37                 if($res) {
38                     $sql = "INSERT INTO task_list(user_email, status, create_time, update_time) VALUES("."‘$user_email‘,0,"."‘".date("Y-m-d H:i:s")."‘,"."‘".date("Y-m-d H:i:s")."‘".")";
39                     $res = mysql_query($sql);
40                     if($res) {
41                         ?>
42                         <script>
43                             $.post(‘send.php‘);
44                         </script>
45                         <?php
46                     }
47                 } else {
48                     echo "<script>alert(‘注册失败‘)</script>";
49                 }
50             }
51         }
52         
53 
54         
55     ?>
56 </body>
57 </html>

content.html代码

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>index</title>
 6 </head>
 7 <body>
 8     <h1>demo</h1>
 9     <table style="color: red;border-collapse: collapse;width: 100%;border: 1px solid red;">
10         <tr>
11             <td>ABCD</td>
12             <td>ABCD</td>
13             <td>ABCD</td>
14         </tr>
15         <tr>
16             <td>ABCD</td>
17             <td>ABCD</td>
18             <td>ABCD</td>
19         </tr>
20     </table>
21 </body>
22 </html>

 

以上是关于php+mysql 模拟队列发送邮件的主要内容,如果未能解决你的问题,请参考以下文章

PHP中的邮件队列

超实用的php代码片段

用php-redis给全部用户发送邮件,数据量很大,思路应该是啥样的

php mail() 是群发邮件的好选择吗?

Lumen 框架使用队列和作业发送电子邮件不工作

Laravel 队列发送邮件