GithubHelp home page GithubHelp logo

peppeocchi / php-cron-scheduler Goto Github PK

View Code? Open in Web Editor NEW
786.0 40.0 142.0 195 KB

PHP cron job scheduler

License: MIT License

PHP 100.00%
scheduled-jobs schedules-execution scheduler-commands php-cron-scheduler schedule

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

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?

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.

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!

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?

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?

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

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?

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.

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');

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}");
                }
            });

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.

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

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

cron seconds

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

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! 👍

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 !

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.

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?

Ping url

Schedule ping url (optionally pass parameters)

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

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

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.

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,

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.

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

?>

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);
});

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?

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.

->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.

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

problem with exec function

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

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.

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

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

Javascript in php

Hi, Does this support javascript or jquery in php file

Thanks

Siba

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.