CodeIgniter Cron Job on Shared Hosting?
Asked Answered
R

4

4

I am trying to learn how to do my first cron job using CodeIgniter. In the past, it seemed the only way to do this with CI was to use the wget command instead of php.

The CodeIgniter User Guide, however, says that now you can do this from the command line, for example by running:

$ cd /path/to/project;
$ php index.php controller method

This works great using Terminal on my local setup. But when I use a similar command in the cron section of cPanel on my shared hosting, the task just returns the contents of index.php.

I'm not entirely sure what cPanel does with this command, so unsure as to whether it's using the command line at all.

Could someone explain how I might be able to set up a cron job on shared hosting using CodeIgniter please?

Here is the example code from the CodeIgniter user guide:

tools.php

public function message($to = 'World')
{
    echo "Hello {$to}!".PHP_EOL;
}

} ?>

Regalia answered 30/11, 2011 at 20:7 Comment(2)
What is it that you're controller method does?Garment
Well at the moment I'm just trying the Hello World example in from the CodeIgniter User Guide. Why, how might that affect the answer?Regalia
B
3

It's going to depend on your host. Cron jobs could really screw stuff up if you're not careful, so a lot of shared hosts don't allow it. You probably need to be on some virtual container (like a VPS, virtuozo, etc.) to do this. This isn't a CodeIgniter issue, but a hosting provider issue. Call them first.

Bresnahan answered 30/11, 2011 at 20:28 Comment(2)
Whilst I'm sure you're right, I'm able to run a cron job just fine using normal PHP and putting the file in the CodeIgniter root. But I feel much more comfortable using CodeIgniter than just PHP on its own.Regalia
OK, good to know. In your cron definition, are you using the full path to the php binary? Also, make sure you're not referencing $_SERVER or any globals that aren't defined in CLI. Last thing I'd check is whether gzip is screwing up your output. I'm sure there's more, but those are the first off the top of my head...Bresnahan
I
0

We worked around this exact issue as follows:

  1. Set up a normal php file that is scheduled by cron. Nothing to do with codeigniter yet
  2. Inside it, you can make an fsocket or curl request to perform your regular CodeIgniter call as you do from the web.

Here's an example (say, cron.php)

#!/usr/local/bin/php.cli
<?php
DEFINE('CRON_CALL_URL','https://my_server/'); // 

DEFINE('CRON_HTTPS_PORT', 443); // port to use during fsocket connetion
DEFINE('CRON_SSL_PREFIX', 'ssl://'); // prefix to be used on the url when using ssl
$current_time = now();
$md5_hash = md5('somevalue'.$current_time);
        $url = CRON_CALL_URL.'MYCTRL/MYMETHOD'; 
        $parts=parse_url($url);
        // 
        $parts['query']='md5_hash='.$md5_hash.'&time='.$current_time;    
        $fp = fsockopen(CRON_SSL_PREFIX.$parts['host'],
            isset($parts['port'])?$parts['port']:CRON_HTTPS_PORT,
            $errno, $errstr, 30);

        if (!$fp) {
        } else {

            if (!array_key_exists('query', $parts)) $parts['query'] = null;
            $out = "POST ".$parts['path']." HTTP/1.1\r\n";
            $out.= "Host: ".$parts['host']."\r\n";
            $out.= "Content-Type: application/x-www-form-urlencoded\r\n";
            $out.= "Content-Length: ".strlen($parts['query'])."\r\n";
            $out.= "Connection: Close\r\n\r\n";
            if (isset($parts['query'])) $out.= $parts['query'];

            fwrite($fp, $out);
            fclose($fp);
        }
}
?>

NOTE: Make sure that in your MYCTRL/MYMETHOD function you have

ignore_user_abort(true);

that way when you fsocket connection is closed, your script will still run to the end.

We actually have a bunch of these fsockets for various reasons. If you need to make sure that the call to that controller/method came from the cron script, you need to pass some additional hash values so that only cron and the script know it. Once the script is called it has access to any codeigniter functions. Works like a charm.

Invoke answered 30/11, 2011 at 20:52 Comment(0)
D
0

I've set up 100s of CI cronjob on shared hosting like this: create a short php script which calls the CI controller as if it was a webbrowser.

So, script.php contains this:

      script #! /usr/local/bin/php -f /home/example/public_html/script.php 

  <?php
     get_get_contents('http:example.com/cronjob/');     
  ?>

Then set your cronjob in cPanel to call script.php When it runs Script.php will call the Codeigniter Cronjob controller. There you have the entire CI framework at your disposal.

Donaldson answered 22/5, 2013 at 2:26 Comment(0)
M
0

If you are going to call it like a web browser, why not replace the cronjob command with:

wget http://example.com/cronjob/

instead of creating something new or simply

curl --suppress http://example.com/cronjob/`
Mikael answered 21/11, 2015 at 8:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.