Writing Cron Jobs and Command Line Scripts in CodeIgniter

Building a command line interface into your application can be a way to add extra utility to your application. Adding cron jobs (a.k.a. scheduled tasks) to your CodeIgniter application can provide additional utility. In this article, we’ll show you how to set up both in a CodeIgniter application by writing a simple appointment reminder, which will remind people if they have an appointment scheduled a day in advance.

Running Code Via The Command Line

You can access all CodeIgniter controller methods via the command line. Let’s start with a simple controller:

<?php
class Hello extends CI_Controller
{
  public function index()
  {
    echo "Hello, World" . PHP_EOL;
  }

  public function greet($name)
  {
   echo "Hello, $name" . PHP_EOL;
  }
}

From the application root folder, to call the index function we can do the following:

php index.php hello

By passing the name of the controller to index.php, we can invoke the index method of the controller. If we want to invoke other methods, we can pass them as the next arguments. Any arguments proceeding those will be passed as arguments to the method we are calling. So, to get the output of “Hello, Glenn” from this controller, we would run the following:

php index.php hello greet Glenn

Detecting command line requests

You may want to write controller methods that behave differently based on whether or not they are accessed via the command line. you can do this by using the input library, which has a function called is_cli_request() to detect if a request to a controller is from the command line or not. Here is an example if you want to make a method only accessible via command line:

 <?php public function greet($name) { if(!$this->input->is_cli_request())
      {
          echo "greet my only be accessed from the command line";
          return;
      }
      echo "Hello, $name" . PHP_EOL;
  }

Setting up the Appointment Reminder

Let’s say we have a system where people can book appointments. We would like to send them a reminder a day in advance that they have an appointment coming up. In this tutorial, we will set up a command line script Let’s set up our appointment reminder files. First let’s start by building the table.

CREATE TABLE appointments (
id int auto_increment primary key,
email varchar(255) not null default ”,
start_time datetime
is_reminded tinyint(1) not null default 0
);

Now, we’ll write a model that will perform the two primary data functions we need for this appointment reminder: a way to fetch all appointments on a particular day and a way to mark appointments that have recieved reminders so that we do not send multiple reminder emails:

class Appointment_model extends CI_Model
{
  public function get_days_appointments($day)
  {
    $day_start = date('Y-m-d 00:00:00', $day);
    $day_end = date('Y-m-d 23:59:59', $day);
    return $this->db->select('*')
      ->from('appointments')
      ->where('start_time <', $day_start) ->where('start_time >', $day_end)
      ->get()->result();
      
  }

  public function mark_reminded($appointment_id)
  {
    return $this->db->where('id', $appointment_id)->update('appointments', array('is_reminded' => 1));
  }
}

Now that we can handle all the data transactions through the model. Let’s write a controller so we can access this through the command line. In this example, we will put the logic in the index() function, since that is all this controller does. Personally, I like to put all of my command line scripts inside a folder named ‘cli’ inside of the controllers folder.

<?php class Reminders extends CI_Controller { public function __construct() { parent::__construct(); $this->load->library('input');
    $this->load->library('email');
    $this->load->model('Appointment_model');
  }
  public function index()
  {
    if(!$this->input->is_cli_request())
  {
      echo "This script can only be accessed via the command line" . PHP_EOL;
      return;
  }
  $timestamp = strtotime("+1 days");
  $appointments = $this->Appointment_model->get_days_appointments($timestamp);
  if(!empty($appointments))
  {
      foreach($appointments as $appointment)
      {
          $this->email->set_newline("\r\n");
          $this->email->to($appointment->email);
          $this->email->from("youremail@example.com");
          $this->email->subject("Appointment Reminder");
          $this->email->message("You have an appointment tomorrow");
          $this->email->send();
          $this->Appointment_model->mark_reminded($appointment->id);
      }
  }
  }
}

Whenever you call this command line script, it will set an email to all people who have an appointment the next day. It will also mark their appointments as reminded to ensure that we do not send multiple emails to the same individual for the same appointment.

Setting up a Cron Job (Scheduled Task)

We would like to call this command line script once a day, at 1 pm. You can edit the cron jobs your server runs with the following command:

crontab -e

each line of the crontab file takes six arguments, which are, in order:

  • minutes (0 to 59)
  • hours (0 to 23)
  • day of month (1 to 31)
  • month (1 to 12)
  • day of week (0 – 6)
  • command (command to be executed)

you can use commas to seperate multiple values (so 1,3,5 in the day of week field will be every Monday, Wednesday, and Friday) , dashes to represent ranges(so 09-17 in the hour field means every hour on the hour from 9am to 5pm) and * for wildcards. (so * in the hours fields means every hour on the hour)

Since we would like this script to run once a day at 1pm, our new entry into the crontab file would look like this:

0 13 * * * php [application_path]/index.php cli/reminders

And now we can send out appointment reminders once a day. This Article Has a lot of good examples for other ways to set up your scheduled tasks.

I also have a small helper file I use in CodeIgniter to make formatting output easier. You can check it out over on Github.

cli_helper on Github

Click Here to Leave a Comment Below 11 comments
Daniel Gonzalez - last year

It was really helpful. Thank you so much.

Reply
Abdul Mujeeb - last year

thank you sir but i want to full explain hwo to setup cronjob and how to initialize and how to call it so please give me example in codeigntier thank you

Reply
Vikash - last year

hi GStovall, I am facing below mentioned issue while excuting cron ..

Error : Could not open input file: /var/www/2017/Codeigniter/ak/application/index.php

Configured url in terminal : php /var/www/2017/Codeigniter/ak/application/index.php cli/cron

Reply
Jvandemerwe - last year

Thank you, this was very helpful. I have now my cron manager working in my own program.

Reply
How do I Create a Portfolio Before I Have Clients? - last year

[…] in the past. It has led to some dry articles like “How to test controllers in Rails 4”, or “How to write a command line tool in CodeIgniter.” But such items have generated traffic. They are also an excellent way to “upcycle” your […]

Reply
Prabhu Umapathy - 8 months ago

I have followed same. But cron job is not working.
My cron URL
php /public_html/santoshnair.in/auto_generate/cron.php >/dev /null

Reply
Prabhu Umapathy - 8 months ago

How to commend crontab -e ?

Reply
Vincitore - 6 months ago

Did any one face session issue?

I set email when cron job run and I am getting this kind of email when cron job run

X-Powered-By: PHP/5.6.32
Set-Cookie: ci_session=0hc1h3h06c6ui1ljvgpcal016ld4db46; expires=Tue, 30-Jan-2018 12:55:01 GMT; Max-Age=7200; path=/; HttpOnly
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-type: text/html; charset=UTF-8

followed by Login page HTML.

any suggestion?

Reply
Elaine Collins - 6 months ago

Is there a way I can use cron job on Windows.
I have being trying to use Windows Task Scheduler but i not having any luck. Thanks

Reply
Siva Prasad - a few months ago

Hi , i have a query, that how could we run a cron job for codeigniter project in linode cloud hosting , i couldn’t understand how to give the path for executable function. could you help me out

Reply

Leave a Reply: