PHP实现基于MySQL createDate按日定时发送邮件的方案
嘿,针对你这个需要按每条记录createDate的时分,每天定时发送邮件的需求,我整理了两种实用的方案,你可以根据自己的技术栈和场景来选择:
方案一:纯MySQL内部实现(事件调度器+存储过程)
如果你不想依赖外部脚本,完全在数据库层面搞定的话,可以用MySQL的事件调度器来实现。不过前提是你得先配置好MySQL的邮件发送功能(比如内置的SEND_MAIL或者第三方UDF)。
步骤1:开启MySQL事件调度器
先确认调度器是否开启:
SHOW VARIABLES LIKE 'event_scheduler';
如果结果是OFF,执行下面的命令开启(临时生效,重启MySQL会失效):
SET GLOBAL event_scheduler = ON;
要永久生效的话,在my.cnf(Windows是my.ini)里加一行event_scheduler = ON,然后重启MySQL服务。
步骤2:创建处理邮件的存储过程
写一个存储过程,用来筛选符合条件的记录并发送邮件。这里假设你的表有id(主键)和email(收件人邮箱)字段,记得替换成你实际的表名和字段:
DELIMITER // CREATE PROCEDURE SendDailyReminderEmails() BEGIN DECLARE done INT DEFAULT FALSE; DECLARE rec_id INT; DECLARE rec_email VARCHAR(255); -- 游标遍历:今天日期晚于创建日期,且当前时分和创建时分完全匹配的记录 DECLARE cur CURSOR FOR SELECT id, email FROM your_table WHERE DATE(NOW()) > DATE(createDate) AND TIME(NOW()) = TIME(createDate); DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; OPEN cur; read_loop: LOOP FETCH cur INTO rec_id, rec_email; IF done THEN LEAVE read_loop; END IF; -- 这里写发送邮件的逻辑,比如用MySQL的SEND_MAIL函数(需提前配置邮件服务器) -- 示例:SEND_MAIL('your-sender@example.com', rec_email, '每日提醒', '这是你的定时提醒邮件'); END LOOP; CLOSE cur; END // DELIMITER ;
步骤3:创建定时事件
因为要精确到分钟,我们设置每分钟执行一次存储过程,检查当前时分是否匹配记录的创建时分:
CREATE EVENT DailyEmailTrigger ON SCHEDULE EVERY 1 MINUTE STARTS CURRENT_TIMESTAMP DO CALL SendDailyReminderEmails();
这样每分钟都会自动检查,找到符合条件的记录就发邮件。
方案二:外部定时任务+脚本(更灵活,推荐)
如果觉得数据库里发邮件太受限,或者想更灵活控制邮件内容,推荐用外部定时任务(比如Linux Cron、Windows任务计划)配合脚本实现,这样调试和维护都更方便。
步骤1:写查询发送脚本(以Python为例)
用Python连接数据库查询,然后调用SMTP发邮件。先安装依赖:pip install mysql-connector-python,然后写脚本send_daily_emails.py:
import mysql.connector import smtplib from datetime import datetime from email.mime.text import MIMEText # 数据库配置,替换成你的实际信息 db_config = { 'user': 'db_username', 'password': 'db_password', 'host': 'localhost', 'database': 'db_name' } # 邮件服务器配置,替换成你的SMTP信息 smtp_config = { 'server': 'smtp.example.com', 'port': 587, 'username': 'your-sender@example.com', 'password': 'smtp_password' } def send_reminder_email(to_email): """发送提醒邮件的函数""" msg_content = "这是你的每日定时提醒邮件,记得查收哦!" msg = MIMEText(msg_content, 'plain', 'utf-8') msg['From'] = smtp_config['username'] msg['To'] = to_email msg['Subject'] = '每日定时提醒' with smtplib.SMTP(smtp_config['server'], smtp_config['port']) as server: server.starttls() server.login(smtp_config['username'], smtp_config['password']) server.send_message(msg) def main(): # 获取当前时分,用来匹配记录的createDate时分 current_hour_minute = datetime.now().strftime('%H:%M') # 连接数据库 conn = mysql.connector.connect(**db_config) cursor = conn.cursor(dictionary=True) # 查询符合条件的记录:今天日期大于创建日期,且创建时间的时分等于当前时分 query = """ SELECT * FROM your_table WHERE DATE(NOW()) > DATE(createDate) AND DATE_FORMAT(createDate, '%H:%M') = %s """ cursor.execute(query, (current_hour_minute,)) target_records = cursor.fetchall() # 给每条符合条件的记录发邮件 for record in target_records: send_reminder_email(record['email']) # 替换成你的邮箱字段名 # 关闭连接 cursor.close() conn.close() if __name__ == '__main__': main()
步骤2:设置定时任务
Linux系统(Cron)
打开Cron编辑:
crontab -e
添加一行,让让脚本每分钟执行一次:
* * * * * /usr/bin/python3 /full/path/to/send_daily_emails.py
保存退出后,Cron就会自动每分钟运行一次脚本。
Windows系统(任务计划程序)
- 打开「任务计划程序」,点击「创建基本任务」。
- 名称随便填,比如“每日邮件提醒”,下一步。
- 触发器选「每天」,设置开始时间,然后勾选「重复任务间隔」,选「1分钟」,持续时间选「24小时」,下一步。
- 操作选「启动程序」,程序或脚本选你的Python路径(比如
C:\Python39\python.exe),添加参数填脚本的完整路径(比如C:\scripts\send_daily_emails.py),下一步。 - 确认设置,完成即可。
大数据量优化建议
如果你的表有很多记录,每次全表查询会慢,可以加个next_send_time字段来优化:
- 新增字段:
ALTER TABLE your_table ADD COLUMN next_send_time DATETIME NOT NULL; - 初始化现有记录:
UPDATE your_table SET next_send_time = DATE_ADD(createDate, INTERVAL 1 DAY); - 修改查询逻辑为:
SELECT * FROM your_table WHERE next_send_time <= NOW(); - 发完邮件后更新:
UPDATE your_table SET next_send_time = DATE_ADD(next_send_time, INTERVAL 1 DAY) WHERE id = %s;
这样每次只查需要发送的记录,不用全表扫,性能会好很多。
内容的提问来源于stack exchange,提问作者ydlgr

