CakePHP Crontab

Thu, Feb 28, 2008

CakePHP, PHP, Server

Due to the way that CakePHP rewrites URL requests with its router, it might seem confusing to execute a Crontab to run a controller action. I will show you how to set up a cron dispatcher so that you can execute all your different controller action schedules on a single file and pass the controller and action as an argument to the file so that the dispatcher will know which action to fire.

First off, you’ll need to create a duplicate of your index.php file inside of /app/webroot/. Once you have duplicated the file, rename it to cron_dispatcher.php and open it up for editing. On line #77 of your cron_dispatcher.php file, you will see the following :

if (!include(CORE_PATH . ‘cake’ . DS . ‘bootstrap.php’)) {
    trigger_error("Can’t find CakePHP core.  Check the value of CAKE_CORE_INCLUDE_PATH in app/webroot/index.php.  It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR);
 }

The code shown above includes the CakePHP core bootstrap.php file and of course, if the include fails, it triggers an error. So we’ll add an ELSE statement to this code so that we can fire our dispatcher if in fact the boostrap was successfully included. After adding your ELSE statement and the appropriate code to initialize the dispatcher, your code from line #77 should now look like this :

if (!include(CORE_PATH . ‘cake’ . DS . ‘bootstrap.php’)) {
    trigger_error("Can’t find CakePHP core.  Check the value of CAKE_CORE_INCLUDE_PATH in app/webroot/index.php.  It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR);
 } else {
    define(‘CRON_DISPATCHER’, true);
    if($argc == 2) {
        $Dispatcher = new Dispatcher();
        $Dispatcher -> dispatch($argv[1]);
    }
 }

And that’s it. You are ready to start executing cron schedules on this cron_dispatcher.php file and pass your controller together with the action as an argument. Here is an example crontab command :

* * * * * php -q /var/www/vhosts/domain.com/httpdocs/app/webroot/cron_dispatcher.php /products/cron/

The command will execute the the cron_dispatcher.php file and pass the argument “/products/cron/” to it. The argument is equivalent to any controller and action in your CakePHP system. So it is /controller/action/

Good luck! I hope this helps!

, , , , ,

This post was written by:

Antonie Potgieter - who has written 46 posts on Lost-In-Code.

I (Antonie Potgieter) am a software engineer/web developer located in South Africa. My full-time work is the management of Tribulant Software and the development of its software packages.

Contact the author

1 Comments For This Post

  1. Charlotte Says:

    The path of my cron_dispatcher.php is in: /var/www/vhosts/ninthlink.com/httpdocs/pdf/pdfadmin/webroot/cron_dispatcher.php that looks like:
    <?php
    /* SVN FILE: $Id: index.php 7296 2008-06-27 09:09:03Z gwoo $ */
    /**
    * Short description for file.
    *
    * Long description for file
    *
    * PHP versions 4 and 5
    *
    * CakePHP(tm) : Rapid Development Framework
    * Copyright 2005-2008, Cake Software Foundation, Inc.
    * 1785 E. Sahara Avenue, Suite 490-204
    * Las Vegas, Nevada 89104
    *
    * Licensed under The MIT License
    * Redistributions of files must retain the above copyright notice.
    *
    * @filesource
    * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
    * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
    * @package cake
    * @subpackage cake.app.webroot
    * @since CakePHP(tm) v 0.2.9
    * @version $Revision: 7296 $
    * @modifiedby $LastChangedBy: gwoo $
    * @lastmodified $Date: 2008-06-27 02:09:03 -0700 (Fri, 27 Jun 2008) $
    * @license http://www.opensource.org/licenses/mit-license.php The MIT License
    */
    /**
    * Use the DS to separate the directories in other defines
    */
    if (!defined(’DS’)) {
    define(’DS’, DIRECTORY_SEPARATOR);
    }
    /**
    * These defines should only be edited if you have cake installed in
    * a directory layout other than the way it is distributed.
    * When using custom settings be sure to use the DS and do not add a trailing DS.
    */

    /**
    * The full path to the directory which holds “app”, WITHOUT a trailing DS.
    *
    */
    if (!defined(’ROOT’)) {
    define(’ROOT’, dirname(dirname(dirname(__FILE__))));
    }
    /**
    * The actual directory name for the “app”.
    *
    */
    if (!defined(’APP_DIR’)) {
    define(’APP_DIR’, basename(dirname(dirname(__FILE__))));
    }
    /**
    * The absolute path to the “cake” directory, WITHOUT a trailing DS.
    *
    */
    if (!defined(’CAKE_CORE_INCLUDE_PATH’)) {
    define(’CAKE_CORE_INCLUDE_PATH’, ‘/usr/lib/cake’);
    }

    /**
    * Editing below this line should not be necessary.
    * Change at your own risk.
    *
    */
    if (!defined(’WEBROOT_DIR’)) {
    define(’WEBROOT_DIR’, basename(dirname(__FILE__)));
    }
    if (!defined(’WWW_ROOT’)) {
    define(’WWW_ROOT’, dirname(__FILE__) . DS);
    }
    if (!defined(’CORE_PATH’)) {
    if (function_exists(’ini_set’) && ini_set(’include_path’, CAKE_CORE_INCLUDE_PATH . PATH_SEPARATOR . ROOT . DS . APP_DIR . DS . PATH_SEPARATOR . ini_get(’include_path’))) {
    define(’APP_PATH’, null);
    define(’CORE_PATH’, null);
    } else {
    define(’APP_PATH’, ROOT . DS . APP_DIR . DS);
    define(’CORE_PATH’, CAKE_CORE_INCLUDE_PATH . DS);
    }
    }
    if (!include(CORE_PATH . ‘cake’ . DS . ‘bootstrap.php’)) {
    trigger_error(”Can’t find CakePHP core. Check the value of CAKE_CORE_INCLUDE_PATH in app/webroot/index.php. It should point to the directory containing your ” . DS . “cake core directory and your ” . DS . “vendors root directory.”, E_USER_ERROR);
    } else {
    define(‘CRON_DISPATCHER’, true);
    if($argc == 2) {
    $Dispatcher = new Dispatcher();
    $Dispatcher -> dispatch($argv[1]);
    }
    }
    if (isset($_GET['url']) && $_GET['url'] === ‘favicon.ico’) {
    return;
    } else {
    $Dispatcher = new Dispatcher();
    $Dispatcher->dispatch($url);
    }
    if (Configure::read() > 0) {
    echo ““;
    }
    ?>

    I am in the folder: /var/www/vhosts/ninthlink.com/httpdocs/pdf/pdfadmin and on the command line I run:
    php -q /var/www/vhosts/ninthlink.com/httpdocs/pdf/pdfadmin/webroot/cron_dispatcher.php /pdfs/hello

    where my controller is pdfs_controller.php and the function I want to call is:
    function hello()
    {
    die(’hello’);
    }

    But the output is empty:
    [root@www pdfadmin]# php -q /var/www/vhosts/ninthlink.com/httpdocs/pdf/pdfadmin/webroot/cron_dispatcher.php /Pdfs/hello
    [root@www pdfadmin]#

    Please help!! Don’t know what I’m doing wrong. I’ve been looking everywhere but I can’t find out what the problem is. Thank you in advance.

Leave a Reply