简介
过去,你可能需要在服务器上为每一个调度任务去创建 Cron 条目。因为这些任务的调度不是通过代码控制的,你要查看或新增任务调度都需要通过 SSH 远程登录到服务器上去操作,所以这种方式很快会让人变得痛苦不堪。
PHP Cron Scheduler 是一个与框架无关的cron作业调度程序,可以轻松地与您的项目集成或作为独立的命令调度程序运行。在使用这个任务调度器时,你只需要在你的服务器上创建单个 scheduler.php
入口。你的任务调度在scheduler.php
方法中进行定义。
Github仓库:https://github.com/peppeocchi/php-cron-scheduler
如何工作
在项目根目录下创建一个包含以下内容的 scheduler.php
文件。
<?php
require_once __DIR__.'/vendor/autoload.php';
use GOScheduler;
// Create a new scheduler
$scheduler = new Scheduler();
// ... configure the scheduled jobs (see below) ...
// Let the scheduler execute jobs which are due.
$scheduler->run();
然后在crontab
中添加一个新条目,以便每分钟运行 scheduler.php
。
* * * * * path/to/phpbin path/to/scheduler.php 1>> /dev/null 2>&1
就是这样!您的调度程序已经启动并运行,现在您可以添加您的作业,而无需再担心crontab
。这个Cron每分钟都会调用scheduler.php
命令调度器。然后评估你的计划任务并运行到期的任务。
调度作业
默认情况下,您的所有作业将尝试在后台运行。PHP脚本和原始命令默认情况下将在后台运行,而函数将始终在前台运行。您可以通过调用 inForeground()
方法强制命令在前台运行。必须将输出发送到电子邮件的作业将在前台运行。
执行一个PHP脚本
代码语言:javascript复制$scheduler->php('path/to/my/script.php');
php()
方法接受4个参数:
- PHP脚本的路径.
- 要使用的PHP二进制
- 要传递给脚本的参数(注意:您需要在
php.ini
中启用register_argc_argv
才能使其工作(ref)。不要担心它是默认启用的,所以除非你故意禁用它,或者你的主机默认禁用它,否则你可以忽略它。 - 标识符
$scheduler->php(
'path/to/my/script.php', // The script to execute
'path/to/my/custom/bin/php', // The PHP bin
[
'-c' => 'ignore',
'--merge' => null,
],
'myCustomIdentifier'
);
调度原始命令
代码语言:javascript复制$scheduler->raw('ps aux | grep httpd');
raw()
方法接受3个参数:
- 你的命令.
- 要传递给命令的参数
- 标识符
$scheduler->raw(
'mycommand | myOtherCommand',
[
'-v' => '6',
'--silent' => null,
],
'myCustomIdentifier'
);
调度匿名函数
代码语言:javascript复制$scheduler->call(function () {
return true;
});
call()
方法接受3个参数:
- 匿名函数
- 要传递给函数的参数
- 标识符
$scheduler->call(
function ($args) {
return $args['user'];
},
[
['user' => $user],
],
'myCustomIdentifier'
);
所有传入数组的参数都将被注入到函数中。例如:
代码语言:javascript复制$scheduler->call(
function ($firstName, $lastName) {
return implode(' ', [$firstName, $lastName]);
},
[
'John',
'last_name' => 'Doe', // The keys are being ignored
],
'myCustomIdentifier'
);
如果你想传递一个key => value
对,请在arguments
数组中传递一个数组
$scheduler->call(
function ($user, $role) {
return implode(' ', [$user['first_name'], $user['last_name']]) . " has role: '{$role}'";
},
[
[
'first_name' => 'John',
'last_name' => 'Doe',
],
'Admin'
],
'myCustomIdentifier'
);
计划执行时间
有几种方法可以帮助您设置计划的执行时间。如果您不调用此方法中的任何一个,则作业将每分钟(*
)运行一次。
任何表达式
at
-此方法接受dragonmantank/cron-expression
支持的任何表达式
$scheduler->php('script.php')->at('* * * * *');
每分钟执行
everyMinute 每分钟执行。您可以选择传递 minute 以指定作业每 minute 分钟运行一次。
代码语言:javascript复制$scheduler->php('script.php')->everyMinute();
$scheduler->php('script.php')->everyMinute(5);
每小时运行
hourly
每小时运行一次。您可以选择传递您想要运行的 $minute
,默认情况下,它将在每小时的'00'分钟
运行。
$scheduler->php('script.php')->hourly();
$scheduler->php('script.php')->hourly(53);
每天运行
daily 每天运行一次。您可以选择传递 hour 和 minute 以获得更细粒度的控制(或字符串 hour:minute )
代码语言:javascript复制$scheduler->php('script.php')->daily();
$scheduler->php('script.php')->daily(22, 03);
$scheduler->php('script.php')->daily('22:03');
项目应用
项目根目录 scheduler.php
文件
<?php
declare(strict_types=1);
namespace think;
date_default_timezone_set('PRC');
require __DIR__ . '/vendor/autoload.php';
# PHP 二进制文件路径
$bin = '/usr/local/php-8.2/bin/php';
$script = __DIR__ . '/think';
$scheduler = new GOScheduler();
# 2024年4月10日 @add Tinywan 订单自动发货 每天一次凌晨12点半执行
$scheduler->php($script . ' order delivery', $bin)->daily(00, 30);
# 2024年4月10日 @add Tinywan 订单自动取消 5分钟执行一次
$scheduler->php($script . ' order cancel', $bin)->everyMinute(5);
$scheduler->run();