creatortsv / scheduler
独立的包,提供脚本执行计划功能
Requires
- php: >=8.1
- dragonmantank/cron-expression: ^3.3
Requires (Dev)
- phpunit/phpunit: ^10.0
- squizlabs/php_codesniffer: ^3.7
This package is auto-updated.
Last update: 2024-09-19 01:50:55 UTC
README
独立的包,提供脚本执行计划功能。
安装
composer install creatortsv/scheduler
入门指南
开始使用调度器很简单。
use Creatortsv\Scheduler\Registrar\ScheduleRegistrar; use Creatortsv\Scheduler\Scheduler; $job = function (): void { /* your job logic here ... */ } $scheduler = new Scheduler(); $scheduler->getRegistrar()->register($job); $scheduler->run();
上面的例子只是注册了一个简单的闭包函数作为任务,使用默认的cron表达式* * * * *
(这意味着它将每分钟执行一次)并运行它。
Cron表达式
有关Cron表达式对象的完整文档,请访问https://github.com/dragonmantank/cron-expression
每个任务都有自己的cron表达式对象。 ScheduleRegistrarInterface
的 register
方法返回一个默认值为 * * * * *
的cron表达式对象。因此,您可以在任务注册后更改它。
/* Initializing scheduler ... */ $expr = $scheduler->getRegistrar()->register($job); $expr->setExpression('0 */2 * * *'); /* every two days at 00:00 */
调度提供者
有时您想注册多个可以通过特定逻辑分组的工作。在这种情况下,调度提供者更有用。
use Creatortsv\Scheduler\Provider\ScheduleProviderInterface; use Creatortsv\Scheduler\Registrar\ScheduleRegistrarInterface; class MyScheduleProvider implements ScheduleProviderInterface { public function boot(ScheduleRegistrarInterface $registrar): void { // Register specific jobs here ... } }
不要忘记通过调度对象添加您的提供者
/* Initializing scheduler ... */ $scheduler->add(new MyScheduleProvider());
运行调度器
/* Initializing scheduler ... */ $scheduler->run();
默认情况下,调度器使用每个任务的当前 DateTime
对象运行,这意味着它将创建一个 DateTime
对象和每个Cron表达式对象,使用相同的时间戳来确定是否是执行任务的时间。
但有时您需要在特定的timestamp上运行您的调度,例如测试。使用 Scheduler::at
方法更改默认行为。
/* Initializing scheduler ... */ $date = new DateTime(); $date->modify('-3 days'); $scheduler->at($date)->run();
高级用法
有时您可能想控制除了默认行为之外必须执行哪些任务。例如,当前时刻只能运行已注册任务的唯一实例。
在这种情况下,您可以使用 Scheduler::boot
方法而不是 Scheduler::run
。 boot
方法返回 ScheduleIterator
对象,每个项目都是一个必须由给定timestamp执行的作业实例,每个键是给定作业的cron表达式。
让我们想象一下,您有一个确定作业已经在执行中的服务
class JobManager { public function isReleased(SpecificJobInterface $job): bool { /* your logic is here ... */ } }
因此,您可以使用此服务
/* Initializing $scheduler and your $jobManager ... */ foreach ($scheduler->boot() as $job) { if ($job instanceof SpecificJobInterface) { $jobManager->isReleased($job) && $job(); } }
但这是一种更好的做法
/* Initializing $scheduler and your $jobManager ... */ $scheduler->getModerator()->register($jobManager->isReleased(...)); $scheduler->run();
您不必担心作业是否具有不同类型的可调用对象