mikestreety mikestreety - 1 month ago 20
PHP Question

PHP Cron Job Engine

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

Answer

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