1

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.

codeGEN
  • 686
  • 2
  • 18
  • 45

7 Answers7

3

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

CnR
  • 68
  • 1
  • 7
  • On CodeIgniter 3.10, my cron was falling back to default controller because I was using `/usr/bin/php` instead of `/usr/bin/php-cli`. This post has solved the issue for me as well. – Roman T Mar 23 '19 at 10:33
2

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!

Rwd
  • 34,180
  • 6
  • 64
  • 78
  • Yes I am setting it from the cPanel & the command you have mentioned in the first line is pretty much the same command that I have used. But still its not working. – codeGEN Nov 29 '14 at 13:54
  • Can you ssh in to your server? – Rwd Dec 01 '14 at 09:00
  • I tried and it says shell access is not enabled on your server. So no.. I have a .htaccess file on the server as well, do you think it could be routing the php cron job requests as well. – codeGEN Dec 03 '14 at 04:46
  • No, as (unless I'm mistaken) the .htaccess file is purely for apache and cronjobs aren't php specific. Lastly, I assume that you're using your actually `user_name` in the path and not just the string "user_name"? – Rwd Dec 03 '14 at 16:11
  • Yes, I am using the correct username not the user_name string I put out here in the question. I used another cronjob just to echo out a simple string & it worked fine. So the problem really comes when I try to call the codeigniter index.php. Is there any method for me to debug this problem ? – codeGEN Dec 04 '14 at 05:33
  • Ok Thanks. I started a bounty, maybe some one else might come up with an answer. – codeGEN Dec 04 '14 at 11:41
  • If you are getting your default controller then the problem is not calling index.php. For interests sake can you change your default route to direct to controller/method and see if that works? – Mike Miller Dec 04 '14 at 12:16
  • Also what happens if you just call direct from CLI without the CRON? As far as I can see Ross Wilsons answer is correct – Mike Miller Dec 04 '14 at 12:17
  • @MikeMiller I can't check from the CLI because my server doesn't allow shell access. :( .. It works when I call it directly from the browser. – codeGEN Dec 08 '14 at 04:04
1

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.

1

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.

Rajesh Loganathan
  • 11,129
  • 4
  • 78
  • 90
Sergio Varela
  • 53
  • 1
  • 9
0

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

Needhi Agrawal
  • 1,326
  • 8
  • 14
0

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

0

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