通过Cron定时更新数据库表:到期自动将is_premium设为Basic
修复Cron任务的用户会员状态更新代码
原代码存在的核心问题
- 仅处理单条用户数据:
fetch_assoc()只读取查询结果的第一行,无法遍历所有用户 - UPDATE语句语法错误:缺少表名和过滤条件,执行会报错,且会错误修改所有用户的状态
- 错误处理缺失:未检查数据库连接、查询是否成功,出现问题无法定位原因
- 时间处理冗余且易出错:用PHP处理时间存在时区不一致风险,不如直接用数据库时间函数可靠
修正后的代码
<?php $servername = "*"; $dbusername = "*"; $dbpassword = "*"; $dbname = "*"; // 建立连接并检查错误 $con = mysqli_connect($servername, $dbusername, $dbpassword, $dbname); if (!$con) { error_log("数据库连接失败: " . mysqli_connect_error()); exit; } // 直接通过数据库语句批量更新过期会员,效率更高且避免时区问题 $query = "UPDATE users SET is_premium = 'Basic' WHERE is_premium_until < NOW() AND is_premium = 'Premium'"; if (mysqli_query($con, $query)) { error_log("成功更新 " . mysqli_affected_rows($con) . " 条过期会员记录"); } else { error_log("更新失败: " . mysqli_error($con)); } mysqli_close($con); ?>
每小时运行的Cron配置
- 编辑Crontab:
crontab -e - 添加以下任务(替换脚本实际路径):
0 * * * * /usr/bin/php /path/to/your/update_premium.php >> /var/log/premium_update.log 2>&10 * * * *表示每小时第0分钟执行一次- 末尾的日志输出方便后续排查运行问题
关键优化说明
- 用数据库
NOW()函数判断时间,避免PHP服务器与数据库服务器时区不一致导致的判断误差 - 添加
AND is_premium = 'Premium'条件,避免重复执行时修改已为Basic的用户,提升执行效率 - 加入错误日志记录,便于追踪运行中的异常情况
内容的提问来源于stack exchange,提问作者Branson
相关产品推荐
相关产品推荐

