Tagged: script

PHP: Better way to manage your cron rather than writing all in crontab

In PHP , if we are writing the scheduled tasks in core php,

then, we need to setup the individual cron in either crontab in linux or schedule task in windows.

Whenever there are number of crons in a product across multiple platform , it hard to setup all and manage
and one more thing, somehow managing cron is also outside of the code or developer scope in traditional way.

However, the following is not the best way to manage, but still a better way rather than scattered code.

Code : –

<?php
// list of crons
$crons = array(
// command line script
    array(
        "time" => '00 02 * * *',
        'execute' => '/usr/bin/php ' . '/var/www/html/test/cron.php > /dev/null'
    ),
// get url
    array(
        "time" => '*/5 * * * *',
        'execute' => 'wget -O - ' . 'https://developerck.com/test/cron.php'
    )

);

if (empty($_GET['web'])) {
    runcron($crons);
} else {
    printcrons($crons);
}

/*
 * functions to print and run crons
 *
 * if you want to print the list of crons
 * printcrons($crons)
 *
 * runcron($crons) will trye to execute all setup crons
 *
 * (With the above code , you can pass query parameter web to true , ?web=1 to print)
 *
 */

// Printing Crons
function printcrons($crons)
{
    $str = "<table>";
    foreach ($crons as $e) {
        $str .= "<tr>";
        $str .= "<td>" . implode(" ", $e) . "</td>";
        $str .= "</tr>";
    }
    $str .= "</table>";
    echo $str;
}

// function to run crons
function runcron($crons)
{
    // check if shell_exec function is allowd or disabled
    if (function_exists('shell_exec')) {
        foreach ($crons as $c) {
            $time = time();
            // check if it is the time to execute
            if (is_time_cron($time, $c['time'])) {
                // if you wnat to print the command
                echo $command = $c['execute'];
                $str = PHP_EOL . "||" . date("Y-m-d H:i:s") . "||" . $command . PHP_EOL;
                // log all the things under cron.txt
                @file_put_contents("cron.txt", $str, FILE_APPEND);
                // // execute commands
                @shell_exec($command);
            }
        }
    } else {
        echo "shell_exec function does not exist or disabled";
    }
}

// function to check if it is the time to run the cron
function is_time_cron($time, $cron)
{
    $cron_parts = explode(' ', $cron);
    if (count($cron_parts) != 5) {
        // checking for * * * * *
        return false;
    }
    
    $c = explode(' ', $cron);
    $min = $c[0];
    $hour = $c[1];
    $day = $c[2];
    $mon = $c[3];
    $week = $c[4];
    $to_check = array(
        'min' => 'i',
        'hour' => 'G',
        'day' => 'j',
        'mon' => 'n',
        'week' => 'w'
    );
    
    $ranges = array(
        'min' => '0-59',
        'hour' => '0-23',
        'day' => '1-31',
        'mon' => '1-12',
        'week' => '0-6'
    );
    
    foreach ($to_check as $part => $c) {
        $val = $$part;
        $values = array();
        
        /*
         * For patters like 0-23/2
         */
        if (strpos($val, '/') !== false) {
            // Get the range and step
            list ($range, $steps) = explode('/', $val);
            
            // Now get the start and stop
            if ($range == '*') {
                $range = $ranges[$part];
            }
            list ($start, $stop) = explode('-', $range);
            
            for ($i = $start; $i <= $stop; $i = $i + $steps) {
                $values[] = $i;
            }
        } /*
           * For patters like :
           * 2
           * 2,5,8
           * 2-23
           */
        else {
            $k = explode(',', $val);
            
            foreach ($k as $v) {
                if (strpos($v, '-') !== false) {
                    list ($start, $stop) = explode('-', $v);
                    
                    for ($i = $start; $i <= $stop; $i ++) {
                        $values[] = $i;
                    }
                } else {
                    $values[] = $v;
                }
            }
        }
        
        if (! in_array(date($c, $time), $values) and (strval($val) != '*')) {
            return false;
        }
    }
    
    return true;
}

The above code has three functions .

  • is_time_cron () : check whether it is time to run the cron or not
  • printcrons() : if you just want to print the scheduled crons
  • runcron() : you can pass the array of the cron. this function is only needed to call and and it will internally call is_time_cron.
 array("time" => '00 02 * * *',
 'execute' => '/usr/bin/php ' . '/var/www/html/test/cron.php > /dev/null')

Time is the scheduled time at which the cron will run and execute contains the command which needs to be run.

the following https://crontab.guru/ will help you understand the logic behind time ‘ * * * * *’