All Projects → peppeocchi → Php Cron Scheduler

peppeocchi / Php Cron Scheduler

Licence: mit
PHP cron job scheduler

Projects that are alternatives of or similar to Php Cron Scheduler

Activejob Scheduler
A background job scheduler for any queue backend
Stars: ✭ 24 (-95.51%)
Mutual labels:  schedule, scheduled-jobs
Laravel Schedule Monitor
Monitor scheduled tasks in a Laravel app
Stars: ✭ 393 (-26.4%)
Mutual labels:  schedule
linda
Linda is a simple dispatcher library.
Stars: ✭ 12 (-97.75%)
Mutual labels:  schedule
schedulemaker
A course database lookup tool and schedule building web application for use at Rochester Institute of Technology.
Stars: ✭ 52 (-90.26%)
Mutual labels:  schedule
weekplot
Visualize your weekly schedule.
Stars: ✭ 40 (-92.51%)
Mutual labels:  schedule
Zmjganttchart
Full configurable spreadsheet view user interfaces for iOS applications. With this framework, you can easily create complex layouts like schedule, gantt chart or timetable as if you are using Excel.
Stars: ✭ 301 (-43.63%)
Mutual labels:  schedule
auto crawler ptt beauty image
Auto Crawler Ptt Beauty Image Use Python Schedule
Stars: ✭ 35 (-93.45%)
Mutual labels:  schedule
Quartznet
Quartz Enterprise Scheduler .NET
Stars: ✭ 4,825 (+803.56%)
Mutual labels:  scheduled-jobs
Jobrunr
An extremely easy way to perform background processing in Java. Backed by persistent storage. Open and free for commercial use.
Stars: ✭ 331 (-38.01%)
Mutual labels:  scheduled-jobs
jquery-skeduler
This is jQuery plugin which provides you simple scheduler with some items on OX and 24-hours timeline on OY.
Stars: ✭ 23 (-95.69%)
Mutual labels:  schedule
ejyy
「e家宜业」是一整套开源智慧物业解决方案,基于nodejs、typescript、koa、vue开发,包含web中台、业主小程序、员工小程序、公众号、物联网应用等,涵盖业主服务、物业运营、智能物联、数据统计等主要业务。
Stars: ✭ 561 (+5.06%)
Mutual labels:  schedule
memorable-milestones
A GitHub Action that puts your milestones on auto-pilot, using memorable emoji names 🤖
Stars: ✭ 18 (-96.63%)
Mutual labels:  schedule
Spreadsheetview
Full configurable spreadsheet view user interfaces for iOS applications. With this framework, you can easily create complex layouts like schedule, gantt chart or timetable as if you are using Excel.
Stars: ✭ 3,324 (+522.47%)
Mutual labels:  schedule
cron-schedule
A zero-dependency cron parser and scheduler for Node.js, Deno and the browser.
Stars: ✭ 28 (-94.76%)
Mutual labels:  schedule
Wakeupschedule kotlin
Wakeup课程表Kotlin重构版
Stars: ✭ 402 (-24.72%)
Mutual labels:  schedule
edimax-smartplug
Unofficial Edimax Smartplug Libary. Control SP-1101W and SP-2101W from Node.js.
Stars: ✭ 25 (-95.32%)
Mutual labels:  schedule
josk
🏃🤖 Scheduler and manager for jobs and tasks in node.js on multi-server and clusters setup
Stars: ✭ 27 (-94.94%)
Mutual labels:  scheduled-jobs
Laravel Short Schedule
Schedule artisan commands to run at a sub-minute frequency
Stars: ✭ 297 (-44.38%)
Mutual labels:  schedule
Hello Rxjava
可能是学习Rxjava最好的教程之一,另一个是《给Android开发者RxJava的详解》,这个毫无疑问。
Stars: ✭ 526 (-1.5%)
Mutual labels:  schedule
Chronos
Fault tolerant job scheduler for Mesos which handles dependencies and ISO8601 based schedules
Stars: ✭ 4,303 (+705.81%)
Mutual labels:  scheduled-jobs

PHP Cron Scheduler

Latest Stable Version License Build Status Coverage Status StyleCI Total Downloads

This is a framework agnostic cron jobs scheduler that can be easily integrated with your project or run as a standalone command scheduler. The idea was originally inspired by the Laravel Task Scheduling.

Installing via Composer

The recommended way is to install the php-cron-scheduler is through Composer. Please refer to Getting Started on how to download and install Composer.

After you have downloaded/installed Composer, run

php composer.phar require peppeocchi/php-cron-scheduler

or add the package to your composer.json

{
    "require": {
        "peppeocchi/php-cron-scheduler": "3.*"
    }
}

Scheduler V3 requires php >= 7.1, please use the v2 branch for php versions < 7.1.

How it works

Create a scheduler.php file in the root your project with the following content.

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

Then add a new entry to your crontab to run scheduler.php every minute.

* * * * * path/to/phpbin path/to/scheduler.php 1>> /dev/null 2>&1

That's it! Your scheduler is up and running, now you can add your jobs without worring anymore about the crontab.

Scheduling jobs

By default all your jobs will try to run in background. PHP scripts and raw commands will run in background by default, while functions will always run in foreground. You can force a command to run in foreground by calling the inForeground() method. Jobs that have to send the output to email, will run foreground.

Schedule a php script

$scheduler->php('path/to/my/script.php');

The php method accepts 4 arguments:

  • The path to your php script
  • The PHP binary to use
  • Arguments to be passed to the script (NOTE: You need to have register_argc_argv enable in your php.ini for this to work (ref). Don't worry it's enabled by default, so unlessy you've intentionally disabled it or your host has it disabled by default, you can ignore it.)
  • Identifier
$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'
);

Schedule a raw command

$scheduler->raw('ps aux | grep httpd');

The raw method accepts 3 arguments:

  • Your command
  • Arguments to be passed to the command
  • Identifier
$scheduler->raw(
    'mycommand | myOtherCommand',
    [
        '-v' => '6',
        '--silent' => null,
    ],
    'myCustomIdentifier'
);

Schedule a function

$scheduler->call(function () {
    return true;
});

The call method accepts 3 arguments:

  • Your function
  • Arguments to be passed to the function
  • Identifier
$scheduler->call(
    function ($args) {
        return $args['user'];
    },
    [
        ['user' => $user],
    ],
    'myCustomIdentifier'
);

All of the arguments you pass in the array will be injected to your function. For example

$scheduler->call(
    function ($firstName, $lastName) {
        return implode(' ', [$firstName, $lastName]);
    },
    [
        'John',
        'last_name' => 'Doe', // The keys are being ignored
    ],
    'myCustomIdentifier'
);

If you want to pass a key => value pair, please pass an array within the arguments array

$scheduler->call(
    function ($user, $role) {
        return implode(' ', [$user['first_name'], $user['last_name']]) . " has role: '{$role}'";
    },
    [
        [
            'first_name' => 'John',
            'last_name' => 'Doe',
        ],
        'Admin'
    ],
    'myCustomIdentifier'
);

Schedules execution time

There are a few methods to help you set the execution time of your schedules. If you don't call any of this method, the job will run every minute (* * * * *).

  • at - This method accepts any expression supported by dragonmantank/cron-expression
    $scheduler->php('script.php')->at('* * * * *');
    
  • everyMinute - Run every minute. You can optionally pass a $minute to specify the job runs every $minute minutes.
    $scheduler->php('script.php')->everyMinute();
    $scheduler->php('script.php')->everyMinute(5);
    
  • hourly - Run once per hour. You can optionally pass the $minute you want to run, by default it will run every hour at minute '00'.
    $scheduler->php('script.php')->hourly();
    $scheduler->php('script.php')->hourly(53);
    
  • daily - Run once per day. You can optionally pass $hour and $minute to have more granular control (or a string hour:minute)
    $scheduler->php('script.php')->daily();
    $scheduler->php('script.php')->daily(22, 03);
    $scheduler->php('script.php')->daily('22:03');
    

There are additional helpers for weekdays (all accepting optionals hour and minute - defaulted at 00:00)

  • sunday
  • monday
  • tuesday
  • wednesday
  • thursday
  • friday
  • saturday
$scheduler->php('script.php')->saturday();
$scheduler->php('script.php')->friday(18);
$scheduler->php('script.php')->sunday(12, 30);

And additional helpers for months (all accepting optionals day, hour and minute - defaulted to the 1st of the month at 00:00)

  • january
  • february
  • march
  • april
  • may
  • june
  • july
  • august
  • september
  • october
  • november
  • december
$scheduler->php('script.php')->january();
$scheduler->php('script.php')->december(25);
$scheduler->php('script.php')->august(15, 20, 30);

You can also specify a date for when the job should run. The date can be specified as string or as instance of DateTime. In both cases you can specify the date only (e.g. 2018-01-01) or the time as well (e.g. 2018-01-01 10:30), if you don't specify the time it will run at 00:00 on that date. If you're providing a date in a "non standard" format, it is strongly adviced to pass an instance of DateTime. If you're using createFromFormat without specifying a time, and you want to default it to 00:00, just make sure to add a ! to the date format, otherwise the time would be the current time. Read more

$scheduler->php('script.php')->date('2018-01-01 12:20');
$scheduler->php('script.php')->date(new DateTime('2018-01-01'));
$scheduler->php('script.php')->date(DateTime::createFromFormat('!d/m Y', '01/01 2018'));

Send output to file/s

You can define one or multiple files where you want the output of your script/command/function execution to be sent to.

$scheduler->php('script.php')->output([
    'my_file1.log', 'my_file2.log'
]);

// The scheduler catches both stdout and function return and send
// those values to the output file
$scheduler->call(function () {
    echo "Hello";

    return " world!";
})->output('my_file.log');

Send output to email/s

You can define one or multiple email addresses where you want the output of your script/command/function execution to be sent to. In order for the email to be sent, the output of the job needs to be sent first to a file. In fact, the files will be attached to your email address. In order for this to work, you need to install swiftmailer/swiftmailer

$scheduler->php('script.php')->output([
    // If you specify multiple files, both will be attached to the email
    'my_file1.log', 'my_file2.log'
])->email([
    '[email protected]' => 'My custom name',
    '[email protected]'
]);

You can optionally customize the Swift_Mailer instance with a custom Swift_Transport. You can configure:

  • subject - The subject of the email sent
  • from - The email address set as sender
  • body - The body of the email
  • transport - The transport to use. For example if you want to use your gmail account or any other SMTP account. The value should be an instance of Swift_Tranport
  • ignore_empty_output - If this is set to true, jobs that return no output won't fire any email.

The configuration can be set "globally" for all the scheduler commands, when creating the scheduler.

$scheduler = new Scheduler([
    'email' => [
        'subject' => 'Visitors count',
        'from' => '[email protected]',
        'body' => 'This is the daily visitors count',
        'transport' => Swift_SmtpTransport::newInstance('smtp.gmail.com', 465, 'ssl')
            ->setUsername('username')
            ->setPassword('password'),
        'ignore_empty_output' => false,
    ]
]);

Or can be set on a job per job basis.

$scheduler = new Scheduler();

$scheduler->php('myscript.php')->configure([
    'email' => [
        'subject' => 'Visitors count',
    ]
]);

$scheduler->php('my_other_script.php')->configure([
    'email' => [
        'subject' => 'Page views count',
    ]
]);

Schedule conditional execution

Sometimes you might want to execute a schedule not only when the execution is due, but also depending on some other condition.

You can delegate the execution of a cronjob to a truthful test with the method when.

$scheduler->php('script.php')->when(function () {
    // The job will run (if due) only when
    // this function returns true
    return true;
});

Schedules execution order

The jobs that are due to run are being ordered by their execution: jobs that can run in background will be executed first.

Schedules overlapping

To prevent the execution of a schedule while the previous execution is still in progress, use the method onlyOne. To avoid overlapping, the Scheduler needs to create lock files. By default it will be used the directory path used for temporary files.

You can specify a custom directory path globally, when creating a new Scheduler instance.

$scheduler = new Scheduler([
    'tempDir' => 'path/to/my/tmp/dir'
]);

$scheduler->php('script.php')->onlyOne();

Or you can define the directory path on a job per job basis.

$scheduler = new Scheduler();

// This will use the default directory path
$scheduler->php('script.php')->onlyOne();

$scheduler->php('script.php')->onlyOne('path/to/my/tmp/dir');
$scheduler->php('other_script.php')->onlyOne('path/to/my/other/tmp/dir');

In some cases you might want to run the job also if it's overlapping. For example if the last execution was more that 5 minutes ago. You can pass a function as a second parameter, the last execution time will be injected. The job will not run until this function returns false. If it returns true, the job will run if overlapping.

$scheduler->php('script.php')->onlyOne(null, function ($lastExecutionTime) {
    return (time() - $lastExecutionTime) > (60 * 5);
});

Before job execution

In some cases you might want to run some code, if the job is due to run, before it's being executed. For example you might want to add a log entry, ping a url or anything else. To do so, you can call the before like the example below.

// $logger here is your own implementation
$scheduler->php('script.php')->before(function () use ($logger) {
    $logger->info("script.php started at " . time());
});

After job execution

Sometime you might wish to do something after a job runs. The then methods provides you the flexibility to do anything you want after the job execution. The output of the job will be injected to this function. For example you might want to add an entry to you logs, ping a url etc... By default, the job will be forced to run in foreground (because the output is injected to the function), if you don't need the output, you can pass true as a second parameter to allow the execution in background (in this case $output will be empty).

// $logger and $messenger here are your own implementation
$scheduler->php('script.php')->then(function ($output) use ($logger, $messenger) {
    $logger->info($output);

    $messenger->ping('myurl.com', $output);
});

$scheduler->php('script.php')->then(function ($output) use ($logger) {
    $logger->info('Job executed!');
}, true);

Using "before" and "then" together

// $logger here is your own implementation
$scheduler->php('script.php')
    ->before(function () use ($logger) {
        $logger->info("script.php started at " . time());
    })
    ->then(function ($output) use ($logger) {
        $logger->info("script.php completed at " . time(), [
            'output' => $output,
        ]);
    });

Multiple scheduler runs

In some cases you might need to run the scheduler multiple times in the same script. Although this is not a common case, the following methods will allow you to re-use the same instance of the scheduler.

# some code
$scheduler->run();
# ...

// Reset the scheduler after a previous run
$scheduler->resetRun()
          ->run(); // now we can run it again

Another handy method if you are re-using the same instance of the scheduler with different jobs (e.g. job coming from an external source - db, file ...) on every run, is to clear the current scheduled jobs.

$scheduler->clearJobs();

$jobsFromDb = $db->query(/*...*/);
foreach ($jobsFromDb as $job) {
    $scheduler->php($job->script)->at($job->schedule);
}

$scheduler->resetRun()
          ->run();

Faking scheduler run time

When running the scheduler you might pass an DateTime to fake the scheduler run time. The resons for this feature are described here;

// ...
$fakeRunTime = new DateTime('2017-09-13 00:00:00');
$scheduler->run($fakeRunTime);

Job failures

If some job fails, you can access list of failed jobs and reasons for failures.

// get all failed jobs and select first
$failedJob = $scheduler->getFailedJobs()[0];

// exception that occurred during job
$exception = $failedJob->getException();

// job that failed
$job = $failedJob->getJob();

Worker

You can simulate a cronjob by starting a worker. Let's see a simple example

$scheduler = new Scheduler();
$scheduler->php('some/script.php');
$scheduler->work();

The above code starts a worker that will run your job/s every minute. This is meant to be a testing/debugging tool, but you're free to use it however you like. You can optionally pass an array of "seconds" of when you want the worker to run your jobs, for example by passing [0, 30], the worker will run your jobs at second 0 and at second 30 of the minute.

$scheduler->work([0, 10, 25, 50, 55]);

It is highly advisable that you run your worker separately from your scheduler, although you can run the worker within your scheduler. The problem comes when your scheduler has one or more synchronous job, and the worker will have to wait for your job to complete before continuing the loop. For example

$scheduler->call(function () {
    sleep(120);
});
$scheduler->work();

The above will skip more than one execution, so it won't run anymore every minute but it will run probably every 2 or 3 minutes. Instead the preferred approach would be to separate the worker from your scheduler.

// File scheduler.php
$scheduler = new Scheduler();
$scheduler->call(function () {
    sleep(120);
});
$scheduler->run();
// File worker.php
$scheduler = new Scheduler();
$scheduler->php('scheduler.php');
$scheduler->work();

Then in your command line run php worker.php. This will start a foreground process that you can kill by simply exiting the command.

The worker is not meant to collect any data about your runs, and as already said it is meant to be a testing/debugging tool.

License

The MIT License (MIT)

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].