如何在PHP共享主机上每5秒运行短信队列任务?
解决共享主机上每5秒执行短信队列脚本的问题
你遇到的情况在共享主机环境里特别常见——Cron最小间隔卡着5分钟,又没法装Supervisor这类进程管理工具,要实现高频任务确实得换个思路。下面给你两个可行的方案,结合你的现有代码来调整:
方案1:PHP无限循环脚本(生产环境推荐)
这个思路是用Cron每5分钟启动一个持久运行的PHP脚本,脚本内部自己做循环,每5秒执行一次短信发送逻辑。这样既绕开了Cron的间隔限制,又不需要额外工具支持。
改造你的代码:
<?php // 关闭脚本执行时间限制,让脚本可以一直运行 set_time_limit(0); // 即使浏览器/客户端断开连接,脚本也继续执行 ignore_user_abort(true); // 设定每次任务执行的间隔(5秒) $interval = 5; // 无限循环执行任务 while (true) { // 先初始化数据库连接(记得替换成你的实际连接参数) $mysqli = mysqli_connect("你的数据库主机", "用户名", "密码", "数据库名"); if (!$mysqli) { error_log("数据库连接失败: " . mysqli_connect_error()); sleep($interval); continue; } // 关键优化:加状态标记避免重复发送! // 假设你给crbsms_queue表加了status字段,默认值为pending表示待发送 $query_sch = "SELECT * FROM crbsms_queue LEFT JOIN crbusers ON crbsms_queue.user_id = crbusers.user_id WHERE crbsms_queue.status = 'pending'"; $sch_result = mysqli_query($mysqli, $query_sch); if ($sch_result) { foreach ($sch_result as $value) { $phone = $value['phones']; $sender = $value['sender']; $message = $value['message']; $user_id = $value['user_id']; $id = $value['id']; $token = $value["access_token"]; $link_id = NULL; $correlator = "$id"; $endpoint = 'https://example.com/delivery-url.php'; $version = "v1"; // 先标记这条短信为「正在发送」,防止其他循环进程重复处理 mysqli_query($mysqli, "UPDATE crbsms_queue SET status = 'sending' WHERE id = $id"); try { $instance = new BongaTech($token, $version); $sms = new Sms($sender, $phone, $message, $correlator, null, $endpoint); $instance->sendBatchSMS($sms); // 发送成功后标记为「已发送」 mysqli_query($mysqli, "UPDATE crbsms_queue SET status = 'sent' WHERE id = $id"); } catch (Exception $e) { // 发送失败可以标记为「发送失败」,方便后续排查或重试 $errorMsg = mysqli_real_escape_string($mysqli, $e->getMessage()); mysqli_query($mysqli, "UPDATE crbsms_queue SET status = 'failed', error = '$errorMsg' WHERE id = $id"); error_log("短信ID $id 发送失败: " . $e->getMessage()); } } mysqli_free_result($sch_result); } else { error_log("查询短信队列失败: " . mysqli_error($mysqli)); } // 关闭数据库连接,避免资源泄漏 mysqli_close($mysqli); // 等待5秒后执行下一轮任务 sleep($interval); } ?>
部署步骤:
- 把上面的脚本保存为
process_sms_queue.php,上传到你的共享主机目录 - 在Cron面板里添加任务,每5分钟启动一次这个脚本:
这样就算旧脚本因为某种原因意外终止,Cron也会每5分钟补一个新的,保证任务持续运行。*/5 * * * * php /你的主机路径/process_sms_queue.php > /dev/null 2>&1
注意事项:
- 必须加短信状态标记,否则多个脚本实例可能重复发送同一条短信
- 共享主机一般有进程数量限制,Cron设为5分钟间隔比较稳妥,避免同时跑太多进程
- 可以通过
error_log记录关键日志,方便后续排查问题
方案2:HTML页面+定时刷新(仅临时测试用)
如果只是临时需要高频执行任务,可以写个简单的HTML页面,用浏览器定时刷新来触发脚本:
<!DOCTYPE html> <html> <head> <!-- 每5秒自动刷新页面 --> <meta http-equiv="refresh" content="5"> </head> <body> <?php // 这里放你的短信发送逻辑(记得加状态标记避免重复) $mysqli = mysqli_connect("你的数据库主机", "用户名", "密码", "数据库名"); // ... 省略查询和发送代码 ... ?> </body> </html>
这个方案的缺点很明显:必须一直开着浏览器,一旦浏览器关闭或网络断开,任务就停止了,只适合临时测试,绝对不能用于生产环境。
内容的提问来源于stack exchange,提问作者Edward Muss
相关产品推荐
相关产品推荐

