There are two ways to run a cron job:
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.
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 require_once('path/to/yii/framework/yii.php'); // we'll use a separate config file $configFile='path/to/config/cron.php'; // creating and running console application Yii::createConsoleApplication($configFile)->run();
Configuration file should look like this:
return array( // This path may be different. You can probably get it from `config/main.php`. 'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..', 'name'=>'Cron', 'preload'=>array('log'), 'import'=>array( 'application.components.*', 'application.models.*', ), // We'll log cron messages to the separate files 'components'=>array( 'log'=>array( 'class'=>'CLogRouter', 'routes'=>array( array( 'class'=>'CFileLogRoute', 'logFile'=>'cron.log', 'levels'=>'error, warning', ), array( 'class'=>'CFileLogRoute', 'logFile'=>'cron_trace.log', 'levels'=>'trace', ), ), ), // Your DB connection 'db'=>array( 'class'=>'CDbConnection', // … ), ), );
In your crontab add:
php /path/to/cron.php test
Where test is a command name.
Total 4 comments
Hi!
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.
Cheers!
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.
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:
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).
Leave a comment
Please login to leave your comment.