PHP定时通知需依赖系统调度器(如Linux cron或Windows任务计划程序),不可用sleep()等内置方式;通知逻辑须幂等、加状态标记与重试机制,并注意CLI与Web环境差异。

PHP 本身不支持真正的定时任务,得靠系统级调度
PHP 是请求响应型脚本语言,没有内置的后台常驻进程或定时器机制。所谓“PHP 定时发送通知”,本质是让外部调度器(如 Linux cron)定期调用 PHP 脚本,由该脚本执行一次性的消息发送逻辑。
常见误区是试图在 PHP 中用 sleep() 或 pcntl_alarm() 实现长期轮询——这极易导致进程卡死、内存泄漏、超时被 kill,且无法保证精度和可靠性。
- Linux 下用
cron最稳妥:例如每 5 分钟跑一次/usr/bin/php /var/www/notify.php - Windows 可用任务计划程序(Task Scheduler),触发命令为
php.exe C:\path\to\notify.php - 不要在 Web 请求中启动后台进程(如
exec("nohup php notify.php &")),权限、路径、环境变量极易出错
通知逻辑必须幂等,避免重复发送
因为 cron 只管“按时触发”,不保证上一次脚本是否执行完、是否成功。若发送逻辑没做状态标记,网络抖动或脚本中途崩溃就可能造成重复推送。
推荐用数据库标记待发任务的状态字段(如 status:0=待处理,1=已发送,2=失败):
SELECT id, user_id, content FROM notifications WHERE status = 0 AND send_at
- 查出一批待发记录后,立即用
UPDATE ... SET status = 1标记为“处理中”(防并发冲突) - 逐条调用短信/邮件/微信模板消息接口;成功则再
UPDATE status = 2,失败则设为3并记录error_msg - 避免用
WHERE status = 0 AND send_at 一次性全量更新——高并发下易锁表
微信/短信等通知接口要加异常兜底和重试控制
第三方通知服务(如腾讯云短信、微信公众号模板消息)常因签名过期、配额超限、网络超时返回失败。PHP 脚本不能假设每次调用都成功。
- 对
curl_exec()或 Guzzle 响应必须检查$http_code !== 200和业务错误码(如微信返回"errcode":40001) - 单条消息最多重试 2 次,间隔用
usleep(500000)避免被限流 - 把失败消息写入独立日志文件(如
/var/log/notify_failed.log),含时间、ID、原始响应体,方便人工补发 - 别在循环里无条件
die()或exit(),否则后续消息全被跳过
注意时区、字符编码和 CLI 环境差异
Web 环境和 CLI(cron 调用)的 PHP 配置可能不同:时区、max_execution_time、memory_limit、扩展加载情况都可能不一致。
- 脚本开头强制设置时区:
date_default_timezone_set('Asia/Shanghai'); - CLI 下默认
memory_limit常为 -1(不限制),但线上建议显式设为256M防止失控 - 微信模板消息要求
UTF-8编码,若数据来自 MySQL,确认连接使用SET NAMES utf8mb4 - 用
php -i | grep timezone和php -m分别检查 CLI 环境的时区与扩展,和 Web 的phpinfo()对比
真正难的不是写那几行发送代码,而是让整个链路在无人值守时稳定跑满一年不出错——状态标记、失败隔离、环境一致性,缺一不可。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











