Skip to content

Cron job bootstrapper

World Wide Web Server edited this page Jul 4, 2012 · 14 revisions

Category:Config | Category:Config::Community | Category:Config::Cron

This is a simple bootstrapper file that you can use to directly run your CodeIgniter controllers from the commandline. It's a [b]very easy[/b] and elegant solution for using CI controllers for cron jobs. It also supports [b]logging[/b].

[h2]Installation[/h2]

  1. Copy the code at the bottom of this code and save it in a file called [b]cron.php[/b] anywhere on your server (but not in the document root!).

  2. Set the CRON_CI_INDEX constant to the full absolute file/path of your CodeIgniter index.php file

  3. Make this file directly executable: [code]chmod a+x cron.php[/code]

[h2]Usage[/h2] You can use this file to call any controller function: [code]./cron.php --run=/controller/method [--show-output] [--log-file=logfile] [--time-limit=N] [--server=http_server_name][/code]

[h3]Command options[/h3] [code]--run=/controller/method[/code] (Required) The controller and method you want to run.

[pre]--show-output[/pre] (Optional) Display CodeIgniter's output on the console (default: don't display)

[pre]--log-file=logfile[/pre] (Optional) Log the date/time this was run, along with CodeIgniter's output

[pre]--time-limit=N[/pre] (Optional) Stop running after N seconds (default=0, no time limit)

[pre]--server=http_server_name[/pre] (Optional) Set the $_SERVER['SERVER_NAME'] system variable (useful if your application needs to know what the server name is)

[h3]Troubleshooting[/h3]

[b]"I get this error when I try to execute ./cron.php:"[/b] [code]Invalid interpreter: /usr/bin/php^M[/code]

This is caused by not having UNIX-style line breaks, which usually happens by copying files created on other operating systems. Use this command to convert the line breaks to UNIX format:

[code] mv cron.php cron.old tr -d '\15\32' < cron.old > cron.php rm cron.old [/code]

[b]cron.php bombs around line 111:[/b] [code]require(CRON_CI_INDEX); // Main CI index.php file[/cron] This would only happen if you don't have the path to your application's main [b]index.php[/b] defined correctly at line 24: [code]define('CRON_CI_INDEX', '/var/www/vhosts/intranet/index.php'); // Your CodeIgniter main index.php file[/code]

[b]"I don't get any errors or output and the script doesn't seem to run. What would cause this?"[/b] Apparently some authentication libraries, such as Michael Wales' Erkana authentication library, cause this sort of behaviour (it's possible that any code that depends on sessions could cause this). Just use some conditional logic testing to see if the CRON constant is defined before auto-loading any authentication libraries.

[h2]The script[/h2]

[code] #!/usr/bin/php <?php

/*
CRON JOB BOOTSTRAPPER
--------------------------------------------------------------

| | By Jonathon Hill (http://jonathonhill.net) | CodeIgniter forum member "compwright" (http://codeigniter.com/forums/member/60942/) | | Created 08/19/2008 | Version 1.2 (last updated 12/25/2008) | |

PURPOSE
This script is designed to enable CodeIgniter controllers and functions to be easily called from the command line on UNIX/Linux systems.

| |

SETUP
1) Place this file somewhere outside your web server's document root
2) Set the CRON_CI_INDEX constant to the location of your CodeIgniter index.php file
3) Make this file executable (chmod a+x cron.php)
4) You can then use this file to call any controller function:
./cron.php --run=/controller/method [--show-output] [--log-file=logfile] [--time-limit=N] [--server=http_server_name]

| |

OPTIONS
--run=/controller/method Required The controller and method you want to run.
--show-output Optional Display CodeIgniter's output on the console (default: don't display)
--log-file=logfile Optional Log the date/time this was run, along with CodeIgniter's output
--time-limit=N Optional Stop running after N seconds (default=0, no time limit)
--server=http_server_name Optional Set the $_SERVER['SERVER_NAME'] system variable (useful if your application needs to know what the server name is)

| | | NOTE: Do not load any authentication or session libraries in controllers you want to run via cron. If you do, they probably won't run right. | |

Contributions:
"BDT" (http://codeigniter.com/forums/member/46597/) -- Fix for undefined constant CRON_FLUSH_BUFFERS error if the --show-output switch is not set (11/17/2008)
"electromute" (http://codeigniter.com/forums/member/71433/) -- Idea for [--server] commandline option (12/25/2008)

| */

define('CRON_CI_INDEX', '/var/www/vhosts/intranet/index.php');   // Your CodeIgniter main index.php file
define('CRON', TRUE);   // Test for this in your controllers if you only want them accessible via cron

Parse the command line

$script = array_shift($argv);
$cmdline = implode(' ', $argv);
$usage = "Usage: cron.php --run=/controller/method [--show-output][-S] [--log-file=logfile] [--time-limit=N] [--server=http_server_name]\n\n";
$required = array('--run' => FALSE);
foreach($argv as $arg)
{
    list($param, $value) = explode('=', $arg);
    switch($param)
    {
        case '--run':
            // Simulate an HTTP request
            $_SERVER['PATH_INFO'] = $value;
            $_SERVER['REQUEST_URI'] = $value;
            $required['--run'] = TRUE;
            break;

        case '-S':
        case '--show-output':
            define('CRON_FLUSH_BUFFERS', TRUE);
            break;

        case '--log-file':
            if(is_writable($value)) define('CRON_LOG', $value);
            else die("Logfile $value does not exist or is not writable!\n\n");
            break;

        case '--time-limit':
            define('CRON_TIME_LIMIT', $value);
            break;
            
        case '--server':
            $_SERVER['SERVER_NAME'] = $value;
            break;

        default:
            die($usage);
    }
}

if(!defined('CRON_LOG')) define('CRON_LOG', 'cron.log');
if(!defined('CRON_TIME_LIMIT')) define('CRON_TIME_LIMIT', 0);

foreach($required as $arg => $present)
{
    if(!$present) die($usage);
}

Set run time limit

set_time_limit(CRON_TIME_LIMIT);

Run CI and capture the output

ob_start();

chdir(dirname(CRON_CI_INDEX));
require(CRON_CI_INDEX);           // Main CI index.php file
$output = ob_get_contents();

if(defined('CRON_FLUSH_BUFFERS')) {
    while(@ob_end_flush());        // display buffer contents
} else {
    ob_end_clean();
}

Log the results of this run

error_log("### ".date('Y-m-d H:i:s')." cron.php $cmdline\n", 3, CRON_LOG);
error_log($output, 3, CRON_LOG);
error_log("\n### \n\n", 3, CRON_LOG);

echo "\n\n";

?> [/code]

Clone this wiki locally