Giter VIP home page Giter VIP logo

php-cron-scheduler's Introduction

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": "4.*"
    }
}

Scheduler V4 requires php >= 7.3, please use the v3 branch for php versions < 7.3 and > 7.1 or 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 unless 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)

php-cron-scheduler's People

Contributors

albertmn avatar andreabonacintefron avatar andreybolonin avatar carstenwindler avatar dhaarbrink avatar jclyons52 avatar jfilla avatar juvelee avatar mark-win avatar mbiagetti avatar pedrotroller avatar peppeocchi avatar sakulb avatar salt-lick avatar tarlepp avatar tim-dreier avatar timonschenzel avatar tobys avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

php-cron-scheduler's Issues

Crons are not being executed.

It took me some time to debug this issue.

We are using your script to schedule raw commands using CronExpressions like ->at("0 3 * * *"). Some of our commands are with doNotOverlap() others are not. We have a total of 20 commands scheduled.

I have observed that when doNotOverlap() is set you, always set the job to run in foreground even if I haven't set the explicitly on the job.

The problem is that the CronExpression isDue() calculates the execution time always using strtotime("now"). Because the execution could take more than one minute and it runs in foreground, the next job picked from the list won't be executed because the isDue will return false, it's not on time anymore because isDue will use now() and not the time the job was scheduled.

Solutions:
1.) I don't understand why you force nonOverlapping jobs to run in foreground. You should remove that line because it doesn't make much sense to me.
2.) You should rewrite your isDue function to use the time when the job was scheduled and not current time which could be several minutes later because of the non-overlapping jobs.

  /**
   * Check if the job is due to run
   *
   * @return bool
   */
  public function isDue()
  {
    return $this->execution->isDue(date("c", $this->time)) && $this->truthTest === true;
  }

I think both 1.) and 2.) solutions should be applied on your script.

problem with exec function

to many shared hosting provider disabled exec and shel_exec function , can i run it without use exec function ?

The After method can not be accessed

The after method is not available for access by php

using "peppeocchi/php-cron-scheduler": "^2.0"

$scheduler->php('script.php')->after(function ($output) use ($logger, $messenger) {
$logger->info($output);
$messenger->ping('myurl.com', $output);
});

Javascript in php

Hi, Does this support javascript or jquery in php file

Thanks

Siba

Updating dependency from mtdowling/cron-expression to dragonmantank/cron-expression

Hello,

Thanks you for all this work. It's awesome.

Are you aware that mtdowling/cron-expression is falling ? According to http://ctankersley.com/2017/10/12/cron-expression-update/ , it seems there is a complete rewrite.

The prototype of CronExpression::factory seems to remain the same in the new project (dragonmantank/cron-expression)

OLD : https://github.com/mtdowling/cron-expression/blob/master/src/Cron/CronExpression.php
NEW : https://github.com/dragonmantank/cron-expression/blob/master/src/Cron/CronExpression.php

I guess there is no problem to update your composer.json to replace "mtdowling/cron-expression": "~1.0" by "dragonmantank/cron-expression/": "~2.0"

Best regards

Vincent

Send Email only on Fail?

I'm using your script inside a loop. So this is just the chunk that runs in the loop. The code uses Guzzle to hit a URL.

Currently, it sends an email every time a job is run. But, I'm trying to figure out how to only send email if Guzzle gives any status code other than 200... or maybe there is a better way?

$scheduler->call(function() use ($siteUrl, $file, $k, $v) {
	$client = new \GuzzleHttp\Client();
	$res = $client->head($siteUrl . $v['url'], [ 'http_errors' => false ]);
	
	$data = [
		'status'   => $res->getStatusCode(),
		'datetime' => date('Y-m-d H:i:s'),
	];
	
	echo json_encode($data);
})
->at($v['runtime'])
->output($file)
->configure([
	'email' => [
		'subject' => "Cron: '{$k}' at {$siteName}",
		'from'      => $config['email']['from'],
		'transport' => $transport,
	]
])
->email([ $toEmail ]);

Any ideas on how to set $toEmail to false inside the anonymous function ... or not send the email?

Thanks.

Run every X minutes

There are some jobs I would like to schedule every x minutes.
I figured I could do it with ->everyMinute(5) or maybe ->hourly('*/5') but both aren't supported.

The latter could work if validateCronRange() is fixed to support it.

For now I use this workaround: ->at('*/5 * * * *'). But it is ugly, and kind of defeats the purpose of using an interface for scheduling.

I would think this is a common enough usage to be supported by the interface.

execution in seconds

Would it be possible to circumvent this scheduling method where it allows only at least every minute and is able to adjust to run for example every 10 seconds?

Ping url

Schedule ping url (optionally pass parameters)

codes don't work?

Im trying to use following code but it never worked for me. Is it possible to you help me to find my problem in this code ?

<?php
require_once __DIR__.'/vendor/autoload.php';

use GO\Scheduler;

$scheduler = new Scheduler();

$scheduler->php('test.php')->everyMinute();

$scheduler->run();

?>

How does it know when was the last time a job ran?

Here is my schedule.php content:

require_once __DIR__ . '/vendor/autoload.php';
use GO\Scheduler;

$scheduler = new Scheduler();
$scheduler->call(function () {
    echo "Hello";

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

$scheduler->run();

I executed $ php schedule.php. As expected, the file /tmp/my_file.log was created and had Hello World! in it.

Immediately after that I emptied out /tmp/my_file.log and ran $ php schedule.php again. Since one minute has not passed, the /tmp/my_file.log should NOT get filled with Hello World! but it did. Why did it?

Jobs are not executing asynchronously

Hey, thanks for the effort.
Was wondering if the scheduler supports running php files asynchronously?
As far as I understood, it is waiting for a job to finish and then moves on to the next one,
So if I have set 10 crawlers to run every minute, it will timeout on first one that takes a minute.
Thanks again

Invalid script path - mark it as failed job

Currently when passing an invalid path for a job to the scheduler (php only), it is throwing an InvalidArgumentException straight away.

It would be a nice to have to instead of throwing the exception (and preventing other valid jobs to run) it will mark it as failed job and it will keep running the other jobs.
This is something already covered when scheduling Closures, so it should be handled only when scheduling php scripts.

Unexpected argument passed into Job->call()'s Closure

Environment

  • PHP 5.6
  • composer require peppeocchi/php-cron-scheduler:^2.3

How to Reproduce

$scheduler = new \GO\Scheduler()

$scheduler->call( 
  function($args) {
    echo $args["foo"]; 
  }, 
  ["foo" => "bar"], 
  "ident"
)->everyMinute();

$scheduler->run();

Expected Behavior

Within the closure, and based on the docs, I expect $args to be an array and for $args["foo"] to equal "bar".

Observed Behavior

However, that actual value of $args is a string that equals "bar".

Possible Solutions

About resetRun()

Hi there,

I'm reading a list of cronjobs from the database but I'm not sure how to use resetRun():

$listCron = $db->query(bla bla bla)

while {

$scheduler->php($file)->at($schedule);
$scheduler->resetRun()->run();
}

or maybe:

while {

$scheduler->php($file)->at($schedule);
}

$scheduler->run();

Many thanks,

->then is called immediately when a job is run and not after the job ends

I have a job that takes 10 secs before it finishes. When I call ->then(function ($output) that function is called immediately and not after the job has finished 10 secs later.

The first thing I do in the ->then(function ($output) function is write the time and it's always something like 2017-10-03 07:14:00, not 2017-10-03 07:14:10

Also, my job produces stdout but $output is always null.

No email when empty output

I use the scheduler to run error reporting cron jobs. It means an output is generated only if there's an error and only then an email should be sent.

Could you add a setting/property/method which skips sending an email when there's no output given?

Run in a time interval

I need to create a task that runs every day between a time interval, for example
Wheels every day every 5 minutes only between 20:00 to 07:00

Send output in body instead of attachment

It'd be great to have the ability to insert a job output directly in the message body, not as an attachment. I receive lots of emails with the output which is always a short plain text and it's quite inconvenient to open every single one.

Besides, it looks like the body specified in the job is always replaced with "Cronjob output attached" defined inaddPart method in Mailer.php

$scheduler->configure([
    'email' => [
        'subject' => 'Test subject',
        'body' => 'Test body',
    ]
]);

/src/GO/Traits/Mailer.php
->setBody($config['body'], 'text/html')
->addPart('<q>Cronjob output attached</q>', 'text/html');

cron seconds

is there any way to use this library to run tasks in less time every minute? ie every 15 seconds for example?

Implement "before" method

The scheduler currently supports a then method, a callback executed after the job runs.

It seems a good idea to have a before method that's being executed before the job runs.

scheduling not working on a specified date

I couldn't get a script run at a specified date..
This is my code... it is not executing at the date specified it is rather executing instantly.. please help me.

$datetorun = new DateTime('2018-09-04 18:48:00');
$scheduler = new Scheduler();
$scheduler->php($pathtophpscripttorun, '/usr/local/bin/php')->run($datetorun);

what am i doing run.. please help.. i want the skip to run at the date specified.

Set for later in the month, but firing anyway

I have a cron job set up like so, following the directions. It's not supposed to fire until the 12th of the month, and this is the 10th:

$renewalemail = new Scheduler();
$renewalemail->php('cron_renewalemail.php')->at('15 10 12 * *');
$renewalemail->run();

But it's firing anyway. What am I doing wrong?
Thanks.

Cannot get email to be sent (version 2.3.1)

Greetings,

I've been turning this problem sideways for the last few hours and hope someone can point out the obvious to me.

Overall, the scheduler works fine. However, I cannot seem to get emails to be sent. Here is my script, which I know is being executed since it's running the scheduled PHP script. I've also tested out the Swift_SmtpTransport (which is why it's abstracted out below), which does send out email successfully using the same parameters.

Any advice would be appreciated. Cheers!
JP

require_once __DIR__.'/vendor/autoload.php';

use GO\Scheduler;

// Create the Transport the call setUsername() and setPassword()
$transport = (new Swift_SmtpTransport('mail.***.com', 789, 'ssl'))
    ->setUsername('scheduler@***.com')
    ->setPassword('***');

$scheduler = new Scheduler([
    'email' => [
        'subject' => 'croncron',
        'from' => 'scheduler@***.com',
        'body' => 'This is the email body',
        'transport' => $transport
    ]
]);

// ... configure the scheduled jobs (see below) ...
$scheduler->php(
    '/absolute/path-to-script.php', // The script to execute
    '/usr/local/bin/php', // The PHP bin
    [
        '--account' => '1'
    ],
    'IdScheduler'
)
    ->everyMinute()
    ->email(['***@***.com']);


// Let the scheduler execute jobs which are due.
$scheduler->run();

exception 'InvalidArgumentException' with message 'There are no commands defined in the "xxx" namespace.'

Was getting this exception when commands were triggered via cron/php-cron-scheduler, but not when I ran them manually.

Found this thread detailing the same issue, but with Dispatcher: Indatus/dispatcher#68

My solution w/ php-cron-scheduler was to specify usr/bin/php-cli instead of php in the cron command:

So this:
php /home/thewcc/www/abc/artisan "abc:run-all-scheduled-jobs" > /dev/null

Became this:
/usr/bin/php-cli /home/thewcc/www/abc/artisan "abc:run-all-scheduled-jobs" > /dev/null

Noting here just in case anyone else comes across a similar problem.

Run worker in background and add jobs from external file

If the worker is running in the background, is it possible to add jobs from another file? Both files are in the same directory, but one file worker.php will run in the background and execute jobs. Another file is a interface for the scheduler, so the web application can add jobs to it whenever it wants.

Also how do you remove jobs?

Thank you in advanced for all the help! 👍

timezone not being used?

First, this is very helpful -- thanks for putting it out!

My server is in UTC, so I'm passing custom timezone to Scheduler as "America/New_York" but it's not taking. Not affected by every()->hour('00') calls but every()->day('9:30') is.

any ideas?

One job for many executionTime definition (AND)

Hi,
is any way to use AND for simple expression (against using when() method) while defining execution time for one Job?
For example (pseudo code):

    $scheduler
        ->php(`some php script`)
        ->at('1 10 * * 1,2,3')
        ->at('1 8 * * 4,5')

Commands are not being run

I have the following set up in a PHP class:

class Cron {
    public function run() {
        $config = [
            "emailFrom" => "[email protected]",
            "emailTo" => "[email protected]"
        ];
  
        $scheduler = new Scheduler($config);  
        $scheduler->call('myFunc')->every()->minute()->output(APPPATH .'logs/cron.log');
    }

    function myFunc() {
        echo 'Message called from cron');
    }
}

I have a cron setup to call this every minute, however myFunc() never gets called. I can see a run method in the Scheduler class which never gets called. Am I missing something obvious in my setup?

Run script at different times depending on conditions

I have a php script I want to run once a month or every day, depending on the value of certain values in a database.

I have no problem getting the variables into scheduler.php, but can't seem to write a function that will accomplish the above.

I've tried various ways of using the function lines you present, but can't get the result I need. What is the best way to do this?

It's not clear from the instructions if I should chain the command all into one thing, but maybe that's the key, like this, which I've seen in another cron scheduler:

$schedule = new Scheduler();

$schedule->php('filetorun.php')
	->at("10 10 10 * *"); 
        ->when(function() {
             if ($strcron) { return true; }
         });
	->output(['logs/cron_renewalemail.log'])
         ->run();

Thank you!

Schedule not running

I am not running the scheduler from cron job.

I start it manually by running this command

php index.php

This is my index.php file :

require_once '/var/www/html/cron/vendor/autoload.php';
use GO\Scheduler;

$myfile = fopen("/var/www/html/cron/newfile".date('Y-m-d H:i:s').".txt", "w") or die("Unable to open file!");
$txt = "John Doe\n";
fwrite($myfile, $txt);
$txt = "Jane Doe\n";
fwrite($myfile, $txt);
fclose($myfile);

$scheduler = new Scheduler();
$scheduler->php('/var/www/html/cron/index.php')->everyMinute();

I want to run this file again but it is not running not even any error in console. nothing,

When i run this manually by php index.php command newFIle.text is created successfully.
It should be created every minute bcz of this line $scheduler->php('/var/www/html/cron/index.php')->everyMinute(); but it is not.

Kindly let me know if i am missing something here

Storing exception on failed job

Hi,

thanks for this library. It would be nice to store exception on failed jobs for debugging. Now you can only access exception message via outputSchedule, which is not enough to debug complex jobs.

Should I send PR?

Class 'GO\Scheduler' not found

I'm facing this issue, I'm a newbie to php, help needed

PHP Fatal error: Uncaught Error: Class 'GO\Scheduler' not found in D:\scheduler.php:6
Stack trace:
#0 D:\test.php(9): include()
#1 {main}
thrown in D:\scheduler.php on line 6

Fatal error: Uncaught Error: Class 'GO\Scheduler' not found in D:\scheduler.php:6
Stack trace:
#0 D:\test.php(9): include()
#1 {main}
thrown in D:\scheduler.php on line 6

Unable to get log or email

I have the following being executed on a cron job every minute

$scheduler = new GO\Scheduler([
    'email' => [
        'subject' => 'Hourly Email History From Attendee Scheduler',
        'from' => ADMIN_EMAIL,
        'body' => 'This is the daily visitors count',
        'transport' => $transport,
        'ignore_empty_output' => true,
    ]
]);

$scheduler->call(
  function($run, $per_minute, $trottle) use ($emailer, $logger) {
    if($emailer->sendAttendeeEmails($run, $per_minute, $trottle) == -1)
    {
      trigger_error(sprintf('These emails failed to send %s' , join(',', $emailer->get_failed())),  E_USER_WARNING);
    }

    echo "Total emails send {$emailer->get_sent()}";
    echo "{$logger->dump()}";
  },
  [
    $NUM_EMAIL_PER_RUN,
    $EMAILS_PER_MINUTE,
    $NUM_SECS_PAUSE_RUN
  ],
  'SchedulerEmail'
  )->at("*/2 * * * *")->output('run.log')->email([
    [
         '[email protected]' => 'Admin Store'
    ],
    '[email protected]'
]);
// Let the scheduler execute jobs which are due.
$scheduler->run();

The above code uses SwiftMailer to execute batch emails every 2 minutes then email and save to a file. While the job runs as expected I get neither an email nor an output file

I'm running PHP 7.0.32 using 2.*

Is it that I cannot run both or is there something else I'm missing here

UPDATE

I'm able now get the logs but not the emails

Try Catch

what would be the best way for me to define a try catch on each task so that one task is not harmed by the other

<?php
            $this->scheduler->call(function () use (&$skyhub) {
                $skyhub->invoice();
            })->at('0,30 * * * *')->then(function ($output) use (&$logger) {
                if (!empty($output)) {
                    $logger->error("Skyhub Invoice - {$output}");
                }
            });

            $this->scheduler->call(function () use (&$skyhub) {
                $skyhub->shipped();
            })->at('0,30 * * * *')->then(function ($output) use (&$logger) {
                if (!empty($output)) {
                    $logger->error("Skyhub Shipped - {$output}");
                }
            });

Crontab doesn't run scheduler.php

Hello,
First of all thanks for PHP Cron Scheduler, I feel that it will simplify my life (but not yet ;)).
However, I can not make the scheduler work, despite reading the readme carefully.

Here is my file scheduler.php
<? php require_once __DIR __. '/ vendor / autoload.php';
use GO \ Scheduler;

$ scheduler = new Scheduler ();

$ scheduler-> call (function () {
    echo "Hello";
     return "world!";
}) -> output ( 'myfile.log');

$ Scheduler-> run (); ?>

And here's what the command crontab -l sends me back (after adding in my crontab):
* * * * * / usr / bin / php /Applications/MAMP/htdocs/test/scheduler.php 1 >> / dev / null 2> & 1

myfile.log file is already creating and even after waiting for many minutes it remains desperately empty.

Note that it works when I do directly in terminal:
/usr/bin/php /Applications/MAMP/htdocs/test/scheduler.php

What's wrong with my approach?

Thanks for your help !

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.