简体   繁体   中英

Cron job outputting the default controller

PROBLEM

I am using CodeIgniter v2.1.4 for my website. I have setup a cronjob to run every 2hours using the following command php -q /home/user_name/www/index.php controller my_method . However this outputs my default controller pages html content (which is my home page's html content).

TRIED

I added another file to my www directory named test.php with a simple echo & it ran correctly, therefore I am sure the problem exists in CI. Also when I access the controller/method that I am trying to execute via a cron job using the browser, it outputs the correct message.

REQUIRED SOLUTION

I used wget -q http://mywebsite.com/controller/my_method as suggested on another thread & it worked properly, but I want to use the php -q way because then I will be able to reject direct access to my script from the browser.

CodeIgniter uses CLI requests. So you need to use PHP CLI.

/usr/bin/php-cli  /home/user_directory/public_html/index.php controller method

If you don't have PHP CLI on your server, there is another option;

You can enable query string on CodeIgniter and try to run like this.

php -q /home/user_directory/public_html/index.php?c=controller&m=method

For more information about to enable query string: CodeIgniter URLS

It should just be (from cPanel):

php /home/user_name/www/index.php controller method

However, if you're using the command line and you've entered crontab -e :

30 2 * * * php /home/username/index.php welcome show

The example above will run 2:30am every day.

Hope this helps!

I apologize for not knowing CodeIgnitre better, but I wanted to mention that command line PHP and PHP via a web server use different environment variables (specifically can use different php.ini files) as well as things like rewrites and other processing that the web server might do (specifically through .htaccess but also in the main config sometimes) that might be causing an issue here.

If you run the phpinfo() function in your PHP script, it will tell you should php.ini file it's using.

I assume you already checked your controller and method and made sure they were spelled exact and correctly (I don't know if capitalization counts for this).

You might do a simple test where you use your CodeIgniter script to echo out which controller and method it THINKS you're asking for. I'm guessing your command line/cron one isn't passing the variables in correctly and it's defaulting to the main home page as a fall back.

What I learnt yesterday is that you need a to restrict functions from controllers to console use only, blocking its web calls at the controller constructor

class Hello extends CI_Controller {
    function __construct() {
        if (isset($_SERVER['REMOTE_ADDR'])) {
            die('Command Line Only!');
        }
        parent::__construct();
    }
    public function message($to = 'World'){
        echo "Hello {$to}!".PHP_EOL;
    }
}

Then, you need to create a cli.php command line file at the root of your ci file

if (isset($_SERVER['REMOTE_ADDR'])) {
    die('Command Line Only!');
}

set_time_limit(0);

$_SERVER['PATH_INFO'] = $_SERVER['REQUEST_URI'] = $argv[1];

require dirname(__FILE__) . '/index.php';

Finally, in order to run the command, you type in your console this:

php cli.php Hello message

Or

php cli.php Hello message "parameter" 

The output would be a "Hello World!" or a "Hello parameter!" , you might need some tweaking to your controllers and function names, more info here link along with the cli documentation from codeigniter.

At root of your project make a executeCron.php file with following content:

#!/usr/local/bin/php
<?php

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

| 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
| -------------------------------------------------------------
|   /controller/method   Required   The controller and method you want to run.

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

*/

    define('CRON_CI_INDEX', dirname(__FILE__)."/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: executeCron.php /login/index \n\n";
    $required = array('--run' => FALSE);
    foreach($argv as $arg)
    {
       /*switch($arg)
        {
           case 'cronRemoveStories/index':*/
                // Simulate an HTTP request
                //$_SERVER['PATH_INFO'] = $arg;
                $_SERVER['REQUEST_URI'] = $arg;
                $_SERVER['REMOTE_ADDR'] = '';
                $required['--run'] = TRUE;
                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();

   if(file_exists(CRON_CI_INDEX)){
        require(CRON_CI_INDEX);           // Main CI index.php file
   }else{
        die(CRON_CI_INDEX." not found.");
   }
   $output = ob_get_contents();
   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);
?>

Now write your controller and Configure Crontab as follow(correct your file path if needed):

0 */2 * * * php /home/user_name/www/executeCron.php --run=/controllername/methodname

In the crontab you can also use the curl which is better to run URL's

So you can do like this

*/10 *  *  *  *     curl 'http://www.example.com/controller/action'

Hope this will help you

I faced the same problem. I tried many things. At the end, the reason on why the index.php was being displayed was because the following line at my config.php was set as "QUERY_STRING"

When I changed it to the following

$config['uri_protocol']= "AUTO";

It worked as expected.

Hope this helps

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM