-
Notifications
You must be signed in to change notification settings - Fork 7.6k
MY Controller
This page describes a standard feature of the CodeIgniter framework - the ability to extend core libraries. It concerns itself with extending Controller only - as this is the most common application of this feature - but the concepts shown here also apply to the other core libraries.
Take care - these instructions are for CodeIgniter 1.7.x - the 2.x release sees MY_ class extenders relocated to app/core - see the relevant documentation for 2.x. CI 2.x controllers also extend CI_Controller instead of just Controller.
We assume here that you have an understanding of CI and MVC fundamentals. You will have read through the User Guide, especially the sections on Controllers and Models.
The subject of extending core controllers is discussed briefly in a few places in the manual - specifically in the Core Classes and Creating Libraries pages.
The intent of extending the core Controller is to provide methods and attributes to all your normal Controllers. There are other ways of providing this kind of pervasive functionality - including Hooks, Libraries and Helpers. You should familiarise yourself with the methods and benefits of those alternatives before assuming the following is the answer to your question.
Finally, it's assumed that you have an application that does something - it doesn't matter what, merely that you have an existing Controller that we can work with here.
Extensions to the core libraries are placed in application/libraries and the file name is determined by adding the $config['subclass_prefix'] to the core library name.
The $config['subclass_prefix'] variable is set in application/config/config.php and by default it is set to 'MY_'. You probably don't want to change this unless you know what you're doing (and if you know what you're doing you're probably not reading this guide).
In any case, this explains why it's usually called the MY_Controller approach.
So, create your file - application/libraries/MY_Controller.php - and fill it with this code:
<?php
class MY_Controller extends Controller {
function MY_Controller () {
parent::Controller();
}
//...
}
Save and quit. Obviously this file doesn't actually do anything useful but we'll get back to that in a minute.
We'll now modify one of your Controllers to work via the MY_Controller. The following code partial is obviously not a fully functional Controller - I'm just showing enough so you know what you have to change. Here we're using the Controller Forum. CodeIgniter encourages users to stick with the PHP4 (constructor name is the same as class name) syntax, but both formats are shown here.
<?php
// Consider these lines in a normal PHP5 Controller:
class Forum extends Controller {
function __construct() {
parent::Controller();
}
//...
}
// If you are using PHP4 constructs, it will look like:
class Forum extends Controller {
function Forum() {
parent::Controller();
}
//...
}
Now, change the relevant lines to look like this:
<?php
// Modify them to look like this instead (for PHP5):
class Forum extends MY_Controller {
function __construct() {
parent::MY_Controller();
}
//...
}
// Or, for PHP4 format:
class Forum extends MY_Controller {
function Forum() {
parent::MY_Controller();
}
//...
}
Now test your application - it will work exactly the same as it did previously. MY_Controller is being loaded - the extra processing time would be difficult to detect, so you'll just have to trust me here.
If you don't trust me - and good for you if so - you can edit the MY_Controller briefly and introduce an obvious syntax error, such as changing parent to patent for example, and then try reloading your page. Revert your error before continuing.
All we've done here is inserted this MY_Controller class in between your normal Controller and the CI Controller class. Previously your Controller was descended directly from the CI core. This is basic OO theory, but if you're not familiar with that then a ludicrous analogy might be that we've just inserted a new generation between you and your dad - with your dad suddenly becoming your grand-dad. You have still inherited the blue eyes and sparkling wit, but it means you can also now inherit (once you create them!) things from this new intermediate ancestor - such as curly hair or date formatters.
Usually people are looking for a way of making functions accessible across all their Controllers - and so we'll make a very simple function in your MY_Controller to demonstrate how this can work.
Edit your application/libraries/MY_Controller.php file again, and modify it to look like this:
<?php
class MY_Controller extends Controller {
function MY_Controller () {
parent::Controller();
}
/**
* Pretty date
*
* Takes an ISO8601 formatted date and returns a human-friendly form,
* by rounding the time to the nearest hour.
* eg. 2009-05-31T15:42:07 ==> "2009-05-31 ~ 4pm"
*
* @param $date_in string (iso8601 date)
* @return string
**/
function pretty_date ( $date_in ) {
if (strlen ($date_in) != 19)
return $date_in; // return in confusion!
$hh = substr ($date_in, 11, 2);
$mm = substr ($date_in, 14, 2);
if ($mm > 30)
$hh++;
if ( ($hh > 23) OR ($hh == '00'))
$hh_string = "midnight";
else
if ($hh > 12)
$hh_string = ($hh - 12) ."pm";
else
if ($hh == 12)
$hh_string = "midday";
else
$hh_string = $hh ."am";
$output = substr ($date_in, 0, 10) ." ~ ". $hh_string;
return $output;
} // end-function pretty_date ()
} // end-class MY_Controller
//...
The pretty_date() function above is particularly useful for ISO8601 timestamps that come in from EXIF information, for example. We'll just use a hard-coded input string here.
Edit your functioning Controller and add in a reference to this function. I'll assume you're using $this->data for your view data, and that you have a view file you can use this in. You'll see that we simply use the $this-> prefix, which will look in the parent controller (in this case MY_Controller) for a matching method or attribute.
<?php
// somewhere in one of your application's Controller files
//...
$this->data['friendly_date'] = $this->pretty_date ("2009-05-31T16:42:07");
//...
$this->load->view ('your_view', $this->data);
//...
In your view you can now echo $friendly_date - so go and make that change to your view file and then reload your web page to confirm that it's all tickety-boo.
Impressive, eh?
This is a fairly trivial example of what you can do with MY_Controller - most people would put a function like pretty_date() into a helper, as it requires no database access, and is only needed for views that have to generate a pretty date from an ISO8601 one.
More often you would use a MY_Controller for 'on-every-page-load' activities like: o calling models to retrieve database information, o setting / retrieving Session data, o applying an authentication layer - often tied in with Session data, o generating common view partials (headers, footers, menus).
As an example of the last one there, have a read of Jedd's header, footer and menu on every page article.