Category: PHP

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 ‘ * * * * *’

Session Management with PHP, part-4

In this part, we will try to cover for three questions

  1. What are the parameters that can be configured?
  2. Can I change the stored location?
  3. Can I  change how the data is being stored in session

So the answer is quite simple

Although there are multiple settings that can be customized as per the need and all the details about those are present on PHP.NET (http://php.net/manual/en/session.configuration.php).  From there you can also check which setting is allowed at which level (i.e can be set per directory or once in php.ini only)

but few of them is more important to know, that we will discuss here

a) session.save_path : it contains the path where your session files are being stored. It is by default in tmp directory.

it can be changed and can be set to your favorite location but one needs to remember about garbage collection in case.

b) session.name :  The name of the session key, By default it is PHPSESSID .  It can be renamed. be aware in case you are also using session id in URL.

c) session.save_handler :    It is the part where you define where to store the session data. By default, it is the file. so your session data is stored in the file. But you can write on your own scheme to handle session data.  You can store the session data in database or memory using memcache or any in any other format. Just you need to write your own session handler. PHP has a default support to file only. Here are more details on this… (Custom Session handler)

d) session.gc_maxlifetime : The maximum time session is valid for in seconds. By default, it is 1440 seconds or 24 minutes.

If you want to use the Session-Id using HTTP Action or in URLs, However, Cookie related settings also need to configured in order to use this effectively

e) session.use_trans_sid : If you want to use session id in the HTTP Action or you can say in the URL.

f) session.trans_sid_tags : which tag is allowed, where PHP will append Session id automatically before sending the response to the browser. It is generally used with url_rewriter.tags . url_rewriter.tags also must allow that tag to rewrite.

g) session.trans_sid_hosts : you can define any number of hosts where you want to use HTTP Action based Session-Id. it might be that in you want to use session id for a particular HOST only.

Cookie Based Settings

h) session.use_only_cookies  : If you want to only use cookies to maintain the session. If it is set to 1, then PHP will only use the cookie to store the session id without considering use_trans_sid .

i) session.use_cookies :  This setting provides you the option if you want to switch on or off the cookie for the session. So if you have setup the use_only_cookies set to 1 and this is set to 0. then PHP would be unable to set up the Session. So while doing changes in these you must consider the related settings as well.

If you are using cookies then

j) session.use_cookies :  This defines the validity of cookie. By default, it is set to 0 means for lifelong. PHP will not set the expiry time in cookie

k) session.cookie_httponly : This is related to security aspect. Most browsers follow a protocol that states that if this flag is setup while setting up the cookie, then they will not allow the javascript to read the cookie. Otherwise, it might be that some malicious javascript can read your session cookie and can utilize in wrong way.

l)  session.cookie_secure : If it is set to one, the cookie will only transfer when the request will be with HTTPS. That is good to use, but remember, if you allow your site to be accessible on both protocol, HTTP, and HTTPS, and want to access the same cookie over both, then this setting can cause you break the session when you switch from HTTPS to HTTP.

Let’s say you access the dashboard after login using HTTPS. and there is another page that is utilizing session but it can be accessed by HTTP as well. In this case, if this setting is one, session values will not be available on that page.

m) session.cookie_domain : specifies the domain to set the session cookie. The default is none at all meaning the hostname of the server which generated the cookie according to cookies specification.

This is important to consider that Chrome and Firefox consider the www.example.com and example.com as two different domains while Internet Explorer consider that same.So if your site allows the user to access the site with www and non-www, then it might be that it is working perfectly in Internet explorer and it is breaking in Chrome and Firefox when your user switch between www and non-www version of your site.

For that, you can consider this setting or it can be set up by PHP code session_set_cookie_params().

you can use ‘.example.com’ so that www.example.com and example.com is treated as it is one

n) session.cookie_path : By Default, it is ‘/’ . It means for all path for that HOST.

let’s say you have example.com and you just want to setup the login cookie with a path example.com/afterlogin/ then you can set the path here. so the cookie will be only transferable when the following path is on the request.

“cookie_secure, cookie_httponly, cookie_domain and cookie_path both are the settings to configure the cookie parameter that is being stored on your browser and these are related to browser/client which has support for the cookie. it means we are just directing the browser for how to behave with our cookie.”