ayhome / croantab
Ayhome/croantab 是一个用于 PHP 的 Linux-crontab 命令风格计时器库。
Requires
- php: >=5.5.9
- ext-swoole: >=1.7.20
This package is auto-updated.
Last update: 2024-09-17 09:44:37 UTC
README
这是一个使用类似 Linux crontab 的格式字符串实现定时服务的 PHP 类,依赖于 swoole-extension。
感谢项目 swoole-crontab,我学会了如何分析 crontab 字符串。
DICrontab 与 swoole-crontab 不同,后者是一个完整的应用程序,而 DICrontab 只是一个工具,一个简单的库,一个类,您可以将它包含到您的项目中并使用它。
快速入门
<?php
include './CrontabTicker.php';
$crontab = new \DIServer\Ticker\CrontabTicker();
$crontab->When('0 */20 * * *')
->Then(function ($userParams)
{
echo 'crontab called';
return false;//return false if you want to cancle this cron.
}, $userParams
);
//The callback function will be called every 20 minitues.
如果您只想测试计时器下次何时触发,请使用 Next() 函数代替,Next() 将返回时间表的迭代器。您还可以使用 From(startTime) 假设 cron 从所需时间开始,而不是 time()。
$iterator = $crontab->When('* */20 * * *')
//->From( mktime(14, 00, 00, 3, 3, 2016) )//Optional
->Next();
$count = 0;//only print next 10 cron.
foreach($nextTickTime in $iterator)
{
if($count++ < 10)
echo $nextTickTime;
else
break;
}
//Simple of crontab-string
//$crontabString :
// * 0 1 2 3 4 5
// * * * * * * *
// * - - - - - -
// * | | | | | |
// * | | | | | +----- day of week (0 - 6) (Sunday=0)
// * | | | | +----- month (1 - 12)
// * | | | +------- day of month (1 - 31)
// * | | +--------- hour (0 - 23)
// * | +----------- min (0 - 59)
// * +------------- sec (0-59) (Optional)
//You can use 5 params like what crontab use in Linux, and use the 6th param as to descript the SECONDS.
依赖关系
- 我的开发环境是 CentOS 7。
- PHP 7.0.3
- Swoole-extension 1.8.3
- 我认为 php5.5+ 和 swoole 1.7.7+ 是可以的,但我没有测试过。
- 我使用了 swoole_timer_after,所以至少需要 swoole-1.7.7。
- 它还使用了 PHP 中的 'yield' 关键字,因此需要 5.5+。
注意
由于此类基于 swoole_timer_after,请在使用 swoole_server 或 asyns-swoole-client 时注意以下内容
如果进程被重新加载,cron tick 将被删除,因此如果您想添加一个常驻的 crontab,请记录您的 cron-string 并在进程启动时初始化计时器,一些 swoole 回调(如 'OnWorkerStart')将描述时间表,不用担心计时器会丢失,只需设置一个新的计时器即可。
如果您想执行像向每个用户发送一条消息这样的任务,请注意每个进程都可以有自己的计时器,如果您在 OnWorkerStart 中添加了计时器,假设您有 2 个 Worker 进程和 4 个 TaskWorker 进程,并且在每个 Worker 启动时设置了计时器,您将同时拥有 6 个计时器和回调,每个客户端将接收 6 条消息。因此,请使用类似 "if($server->worker_id==0)" 的方式只添加一个计时器。
描述
在我开发自己的 swoole-framework DIServer-framwork 的过程中,我发现实现一些定时任务(如每周一至周五向每个客户端发送消息)并不容易。swoole_tick 提供了高精度计时服务,但它只能每隔相同的微秒或从现在开始的一定微秒后计时。
我需要的是类似 Linux 中的 crontab,可以使用格式字符串轻松实现,例如 "0 0 * * mon-fri",并且当时间到达时将调用回调函数。
最初我只是想将其用作 DIServer-framwork 的插件,但完成后我发现它是一个独立的工作,因此创建了此项目。
差异
由于 swoole-extension 提供的高精度,与 Linux-crontab 不同,我们可以设置高级 cron,如 "*/20 0 0 * * fri",使用 6 个参数,格式为 "second minute hour day month week";使用 5 个参数的格式为 "minute hour day month week",它将在该分钟的 1 秒时调用,就像 Linux-crontab 一样。
示例
以下是我在测试 Ticker 时使用的一些示例,如果您发现任何错误,请 注释 我。
private $cronString = [
'* */1 * 3 3 *' => 'every seconds in Mar 3th.',
'30 30 21 * * *' => '21:30:30 on every day.',
'15,30,45,0 * 23 * * 6' => 'every 0,15,30,45 seconds in 23 every Saturday.',
'0 0 */1 * * *' => 'every hour at 0 minute and 0 seconds.',
'0 0 4 1 jan *' => 'every 4:00:00 at January 1st.',
'* * 7 * * *' => 'every seconds in 7 o'clock every day.',
'0-59/2 20 0-23/2 * * *' => 'every 2 seconds in every 20 minutes at every 2 hours in a day.',
'0 6-12/3 * 2 *' => 'In February, every 3 hours in 6 o'clock to 12 o'clock.',
'0 17 * * 1-5' => 'every 17:00:01 on Monday to Friday.',
'0 11 4 * mon-wed' => 'Every 11:00:01 on 4th of a month or in Monday to Wednesday',
'10 1 * * 6,0' => 'every 1:10:01 on Saturday and Sunday',
'45 4 1,10,22 * *' => '4:45:01 on every 1st,10th,22th in a month.',
'0,30 18-23 * * *' => 'every 0,30 minutes in 18-23. Tips:23:30 will called.',
'*/1 * * * * *' => 'every seconds',
'* * * * * *' => 'every seconds',
'0 23-7/1 * * *' => 'equals to "0 23,0-7 * * *"',
];
缩写
在使用月份或星期时,您可以使用 'fri' 来代替 '5',表示星期五,缩写支持如下
//Case is ignored
const SHORT_MAP = [
'sun' => 0,
'sunday' => 0,
'mon' => 1,
'monday' => 1,
'tues' => 2,
'tue' => 2,
'tuesday' => 2,
'wed' => 3,
'wednesday' => 3,
'thur' => 4,
'thu' => 4,
'thursday' => 4,
'fri' => 5,
'friday' => 5,
'sat' => 6,
'saturday' => 6,
'jan' => 1,
'january' => 1,
'feb' => 2,
'february' => 2,
'mar' => 3,
'march' => 4,
'apr' => 4,
'april' => 4,
'may' => 5,
'jun' => 6,
'june' => 6,
'jul' => 7,
'july' => 7,
'aug' => 8,
'august' => 8,
'sep' => 9,
'sept' => 9,
'september' => 9,
'oct' => 10,
'october' => 10,
'nov' => 11,
'november' => 11,
'dec' => 12,
'december' => 12
];