PHP轻量级作业调度器 Cron Scheduler

PHP技术
122
0
0
2024-08-15

简介

过去,你可能需要在服务器上为每一个调度任务去创建 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 GO\Scheduler;

// 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脚本
$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'
);
调度原始命令
$scheduler->raw('ps aux | grep httpd');
raw()方法接受3个参数:
  • 你的命令.
  • 要传递给命令的参数
  • 标识符
$scheduler->raw(
    'mycommand | myOtherCommand',
    [
        '-v' => '6',
        '--silent' => null,
    ],
    'myCustomIdentifier'
);
调度匿名函数
$scheduler->call(function () {
    return true;
});
call()方法接受3个参数:
  • 匿名函数
  • 要传递给函数的参数
  • 标识符
$scheduler->call(
    function ($args) {
        return $args['user'];
    },
    [
        ['user' => $user],
    ],
    'myCustomIdentifier'
);

所有传入数组的参数都将被注入到函数中。例如:

$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 分钟运行一次。

$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 )

$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 \GO\Scheduler();

# 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();