使用 php 实现类似 linux crontab 的定时任务功能,支持秒级定时任务类
/**
* Class Crontab
* description: 使用 php 实现类似 linux crontab 的定时任务功能,支持秒级定时
* author: http://www.phpernote.com/
*/
class Crontab {
/**
* 判断某个时间点是否在 cron 规则之内
* @param $cron
* @param $time
* @return bool
*/
public static function parseCron($cron, $time) {
$cronArray = self::getCronArray($cron);
$now = explode(' ', date('s i G j n w', $time));
foreach ($now as $key => $piece) {
if (!in_array($piece, $cronArray[$key])) {
return false;
}
}
return true;
}
/**
* @param $cron
* @return array
*/
public static function getCronArray($cron) {
$cronArray = explode(' ', $cron);
$timeArray = [];
$dimensions = [
[0, 59], //seconds
[0, 59], //Minutes
[0, 23], //Hours
[1, 31], //Days
[1, 12], //Months
[0, 6] //Weekdays
];
foreach ($cronArray as $key => $item) {
list($repeat, $every) = explode('/', $item, 2) + [false, 1];
if ($repeat === '*') {
$timeArray[$key] = range($dimensions[$key][0], $dimensions[$key][1]);
} else {
// 处理逗号拼接的命令
$tmpRaw = explode(',', $item);
foreach ($tmpRaw as $tmp) {
// 处理10-20这样范围的命令
$tmp = explode('-', $tmp, 2);
if (count($tmp) == 2) {
$timeArray[$key] = array_merge($timeArray[$key], range($tmp[0], $tmp[1]));
} else {
$timeArray[$key][] = $tmp[0];
}
}
}
// 判断*/10 这种类型的
if ($every > 1) {
foreach ($timeArray[$key] as $k => $v) {
if ($v % $every != 0) {
unset($timeArray[$key][$k]);
}
}
}
}
return $timeArray;
}
}
使用示例:
include 'Crontab.php';
$cron_list = [
//['cron' => '秒 分 时 日 月 周', 'echo' => '任务名称'],
['cron' => '0 */1 * * * *', 'echo' => '第一个任务执行了'],
['cron' => '0 */2 * * * *', 'echo' => 'www.phpernote.com'],
['cron' => '20 */3 * * * *', 'echo' => '第三个任务执行了'],
['cron' => '5 */5 * * * *', 'echo' => '第四个任务执行了'],
['cron' => '0 41 16 29 * *', 'echo' => '第5个任务执行了']
];
echo date('Y-m-d H:i:s', time()) . "\r\n";
while (true) {
$time = time();
foreach ($cron_list as &$cron) {
$result = Crontab::parseCron($cron['cron'], $time);
if ($result) {
echo date('Y-m-d H:i:s', $time) . ' ' . $cron['cron'] . ' ' . $cron['echo'] . "\r\n";
}
}
//echo date('Y-m-d H:i:s', $time) . "\r\n";
sleep(1);
}
输出结果如下: