Yii 1.1: Implementing cron jobs with Yii


There are two ways to run a cron job:

  • Emulate browser.
  • Run PHP in CLI (console) mode.

Emulating browser

This way is a simplest one since you can use existing controller action.

Add one of the following to your crontab:

GET http://example.com/cron/
wget -O - http://example.com/cron/
lynx --dump http://example.com/cron/ >/dev/null

In spite of this method is simple, there are drawbacks. If we are doing some kind of intensive job, one who know the URL can kill your application sending a lot of requests to it.

You can pass a parameter and check it in your action to make URL harder to find:

if($_GET['key']!='my_secret_key') die();

but this will not solve the problem completely.

Using console application

The best way is to create a console application.

Let's create a console command class /protected/commands/TestCommand.php:

class TestCommand extends CConsoleCommand {
    public function run($args) {
        // here we are doing what we need to do

Creating entry script cron.php:

defined('YII_DEBUG') or define('YII_DEBUG',true);
// including Yii
// we'll use a separate config file
// creating and running console application

Configuration file should look like this:

return array(
    // This path may be different. You can probably get it from `config/main.php`.
    // We'll log cron messages to the separate files
                    'levels'=>'error, warning',
        // Your DB connection

In your crontab add:

php /path/to/cron.php test

Where test is a command name.

Total 6 comments

#18436 report it
Delphine at 2014/10/29 04:58am
This tuto is not clear enough

Every Yii's tuto are too succinct for newbies ! (And I am one of them..)

I think it's simple but I can't understand every step because no example are given, no location are precised, etc. !

  • cron.php call itself ? Why ?
  • A config_cron file is needed ? Where to place it ? What to write into it ?
  • We have to create as much file as method needed ?

How to permit command to communicate with model ?..

... Please, can you underpine your tuto ? :/

#15569 report it
viet at 2013/11/22 04:22am
can't run cron

i run "/usr/bin/php /var/www/html/cron/app/console.php myCron testCron" in command line is ok.but i insert to crontab with "01 * * * * root /usr/bin/php /var/www/html/cron/app/console.php myCron testCron" is not run. I have a mail in root. Error: Unknown action: testCron

Usage: /var/www/html/cron/app/console.php mycron Actions: testCron

help me.

#10307 report it
fleuryc at 2012/10/18 11:48am
Isn't this article outdated?


Comparing this wiki page, and the Console Applications article in the Definitive Guide, I feel like it seems a bit obsolete, and that with the latest versions of Yii, you would't be doing this the same way.

I mean, I guess now we would be using Console Command Action.


#6608 report it
jpablo at 2012/01/20 04:11pm
Advantage of browser emulation

Browser emulation has an important advantage. It avoids to deal with diferent PHP versions from web and CLI and diferent php.ini. Sometimes a script works as expected from the web broser and fails in a command line execution. Or vice versa.

Running all the processes in the same way (through the web server PHP module) ensures a consistent behavior.

#2601 report it
Sarke at 2011/01/22 08:17am
Safe way to emulate the browser

I had to use the web interface when running a cron job because I needed access to the same APC cache, which isn't available from the command line... long story.

Instead of using a $_GET['secret_key'] type of thing, I ended up doing this simple check instead:

if ($_SERVER['SERVER_ADDR'] != '')
    throw new CHttpException(403,'Access denied.');

This ensures that the request is coming from the local server and not from the outside, and can't be guessed or compromised.

Then I set up the cron job like this:


The drawback of course is that you can't access it from a browser manually, but this can easily be done by checking if the user is logged in (something that is hard to fake from the command line).

#2000 report it
sebas at 2010/10/28 09:31am
You can also make it run only one time every XXXX minutes
public function actionIndex{
    $oldtime = Yii::app()->getGlobalState('lastCronTime',0);
    if ($oldTime + 60*60 <time){ // your code can be executed
        // put your code here.
        //You can log the income request here

Leave a comment

Please to leave your comment.

Write new article
  • Written by: samdark
  • Category: How-tos
  • Yii Version: 1.1
  • Votes: +33 / -4
  • Viewed: 87,178 times
  • Created on: Oct 26, 2010
  • Last updated: never
  • Tags: cron, cli