I was wondering how one would go about building a PHP Cron Job "engine".
Essentially I am building a web app with "modules" which go and retrieve data at set intervals. I want these modules to be separate, but they all need to gather data at the same time (roughly) - some are once a day, others every 15 minutes.
With several popular CMS's, you set up a cron job to hit a file every 5 minutes or so - what you can then do is "register" the cron job in each module rather than having to edit the cron tab every time you install a module.
E.g.
*/5 * * * * php /path/to/cron.php
In the module you could then do something like
function task() {
// do some work
}
$cron->register(task())->daily();
Or similar - i'm not quite sure how to achieve it, nor am I sure what to search for!
Edit: I'm not looking for something that will edit the crontab, I am also trying to avoid an SQL database. I know it won't happen magically and I'm happy to edit a master "file" to "install" a module.
Edit 2: I suppose essentially what i'm looking for is like laravel do, but without the database... possible?
Hope it makes sense...
After some more thinking, I managed to solve this.
Each module now has a "cron" folder. The files in there represent the frequency of which to run (e.g. halfHourly.php
or daily.php
).
I then have a PHP class that gets fired at regular intervals, with the type passed as a parameter (e.g. once a day the file gets fired with a "daily" parameter).
Every hour, the hourly, halfHourly and quaterHourly ones run (using a switch statement you can ripple down). So on and so fourth. The disadvantage is there are several cron statements but no database is needed!
Example of the code that runs
// This is done as a switch, so that some tasks can ripple down
switch ($argv[1]) {
case 'daily':
$cron->daily();
case 'hourly':
$cron->hourly();
case 'halfHourly':
$cron->halfHourly();
case 'quarterHourly':
$cron->quarterHourly();
break;
default:
$cron->execute($argv[1]);
}
And the actual cron class:
/**
* Cron
*/
class Cron {
private $modules;
function __construct() {
exec('ls -d /path/to/modules/*/cron', $files, $return);
$this->modules = $files;
}
function execute($time) {
$client = $GLOBALS['client'];
echo PHP_EOL . "\033[1;32mProcessing the " . $time . " crons" . PHP_EOL;
foreach($this->modules as $module) {
$path = $module . '/' . $time . '.php';
if(file_exists($path)) {
echo PHP_EOL . "\033[1;34mExecuting module cron: \033[0;36m" . $module . PHP_EOL . "\033[0m";
include $path;
}
}
}
public function __call($name, $arguments) {
$this->execute($name);
}
}