swoole timer支持毫秒级定时任务,需v4.8.0+版本、启用timer扩展、use swoole\timer、禁用register_shutdown_function;可用after()单次触发或tick()循环执行,须手动clear()避免内存泄漏,动态调整间隔需先clear再重建。

你需要在PHP项目中执行毫秒级精度的定时任务,比如每150毫秒采集一次传感器数据、每300毫秒刷新一次内存缓存状态、或在实时音视频流中做帧级调度——Swoole的Timer模块能直接满足这一需求,无需依赖外部消息队列或Linux cron(后者最小粒度为秒级)。
启用Swoole Timer前的必要准备
确认当前PHP环境已安装Swoole扩展且版本不低于v4.8.0,旧版本Timer不支持毫秒级精度。运行php --ri swoole检查输出中是否包含timer: enabled和version => 4.8.0+。
在项目入口文件顶部添加use Swoole\Timer;,否则后续所有Timer调用会报Fatal error。
【必须关闭PHP的register_shutdown_function机制】,否则毫秒级定时器可能在进程退出时被意外截断——在swoole_http_server或swoole_websocket_server启动前,显式调用ini_set('register_shutdown_function', '0');。
创建毫秒级单次定时任务
方法一:使用Timer::after()执行一次性延迟任务
调用Timer::after(250, function() { echo "250ms后触发\n"; });,数字单位为毫秒,支持小数(如120.5),但实际精度受系统调度影响,通常稳定在±5ms内。
方法二:用Timer::tick()实现重复触发,但只执行一次
先调用$tid = Timer::tick(300, fn() => { echo "触发\n"; Timer::clear($tid); });,注意必须手动清除定时器ID,否则会持续占用内存并无限触发——这是新手最常漏掉的操作。
启动毫秒级循环定时器
第一步:定义回调函数并捕获关键上下文
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
不要在闭包里直接引用大对象(如DB连接、Redis实例),改用use ($redis, $cacheKey)显式传入,避免因闭包长期驻留导致内存泄漏。
第二步:注册周期性定时器
执行$timerId = Timer::tick(180, function() use ($redis, $cacheKey) { $redis->incr($cacheKey); });,此处180代表180毫秒间隔,值必须大于0且小于1000(即严格限定在毫秒级)。
第三步:在进程退出前清理资源
监听Swoole\Event::on('shutdown', fn() => Timer::clear($timerId));,确保服务平滑重启时不会残留未销毁的定时器任务。
动态调整毫秒定时器间隔
方法一:停止原定时器→新建更短/更长间隔的定时器
先调用Timer::clear($oldId),再用新间隔调用Timer::tick()生成$newId,两次操作之间存在微小空窗(通常
方法二:使用Timer::set()修改已有定时器(仅限Swoole v5.0+)
直接执行Timer::set($timerId, ['interval' => 95]);,将原180ms间隔改为95ms,无需中断任务流——但该API在v4.x系列不可用,调用会静默失败。










