Glenn Stovall


Developer, Technical Consultant, Author

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 you application. Adding cron jobs (a.k.a. scheduled tasks) to your CodeIgniter application can provide extra 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

All CodeIgniter controller methods can be accessed via the command line. Let’s start with a simple controller:

application/controllers/hello.php
1
2
3
4
5
6
7
8
9
10
11
12
13
<?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 root application forlder, 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 are able to invoke the index method of the controller. If we want to invoke other methods, we can pass them as the next aguments. 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 wether 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 accesible via command line:

application/controllers/hello.php
1
2
3
4
5
6
7
8
9
10
  <?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.

1
2
3
4
5
6
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 them as appointments that have recieved reminders, so that we do not send multiple reminder emails:

application/models/appointment_model.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
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.

application/controllers/cli/reminders.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?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 this command line script is called, it will set an email to all people who have an appointment the next day. It will also mark there appointments as reminded to insure that we do not send multiple emails to the same person for the same appointment.

Setting up a Cron Job (Scheduled Task)

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

crontab -e

each line of the crontab file takes 6 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

Pricing For Freelance Developers

Book-portrait

Figure out how much to charge for your services. Learn when to bill hourly, when to bill a flat rate, and when to do something completely different.Learn More…

Book-portrait

Freelance Pricing Handbook

Figure out how much to charge for your services. Learn when to bill hourly, when to bill a flat rate, and when to do something completely different.Learn More…

We won’t send you spam. Unsubscribe at any time.