-
Notifications
You must be signed in to change notification settings - Fork 7.6k
MY Controller
[color=green]This page describes a standard feature of the CodeIgniter framework - the ability to extend core libraries. It concerns itself with extending [b]Controller[/b] only - as this is the most common application of this feature - but the concepts shown here also apply to the other core libraries.[/color]
[h2] Overview [/h2] We assume here that you have an understanding of CI and MVC fundamentals. You will have read through the [url="/user_guide"]User Guide[/url], especially the sections on [url="/user_guide/general/controllers.html"]Controllers[/url] and [url="/user_guide/general/models.html"]Models[/url].
The subject of extending core controllers is discussed briefly in a few places in the manual - specifically in the [url="user_guide/general/core_classes.html"]Core Classes[/url] and [url="user_guide/general/creating_libraries.html"]Creating Libraries[/url] pages.
The [b]intent[/b] 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 [url="/user_guide/general/hooks.html"]Hooks[/url], [url="/user_guide/general/creating_libraries.html"]Libraries[/url] and [url="/user_guide/general/helpers.html"]Helpers[/url]. You should familiarise yourself with the methods and benefits of those alternatives before assuming the following is [i]the[/i] answer to your question.
Finally, it's assumed that you have an application that does [i]something[/i] - it doesn't matter what, merely that you have an existing Controller that we can work with here.
[h2] Creating the MY_Controller file [/h2] Extensions to the core libraries are placed in [b]application/libraries[/b] and the file name is determined by adding the [b]$config['subclass_prefix'][/b] to the core library name.
The $config['subclass_prefix'] variable is set in [b]application/config/config.php[/b] and by default it is set to '[b]MY_[/b]'. 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 [b]MY_Controller[/b] approach.
So, create your file - [b]application/libraries/MY_Controller.php[/b] - and fill it with this code: [code] <?php
class MY_Controller extends Controller {
function MY_Controller () {
parent::Controller();
}
}
[/code]
Save and quit. Obviously this file doesn't actually [i]do anything useful[/i] but we'll get back to that in a minute.
[h2] Modifying your existing Controller [/h2]
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 [b]Forum[/b]. CodeIgniter encourages users to stick with the PHP4 (constructor name is the same as class name) syntax, but both formats are shown here.
[code] // 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(); } [/code]
Now, change the relevant lines to look like this: [code] // 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(); } [/code]
Now test your application - it will work exactly the same as it did previously. MY_Controller [i]is[/i] being loaded - the extra processing time would be difficult to detect, so you'll just have to trust me here.
[i]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 [b]parent[/b] to [b]patent[/b] for example, and then try reloading your page. Revert your error before continuing.[/i]
[h3]Theory side note[/h3] All we've done here is inserted this [b]MY_Controller[/b] 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.
[h2] Putting useful stuff in MY_Controller [/h2]
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 [b]MY_Controller[/b] to demonstrate how this can work.
Edit your [b]application/libraries/MY_Controller.php[/b] file again, and modify it to look like this: [code] <?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
[/code]
[h2] Using a MY_Controller method from your Controller [/h2]
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 [b]$this->[/b] prefix, which will look in the parent controller (in this case MY_Controller) for a matching method or attribute.
[code] // 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); ... [/code]
In your view you can now [b]echo $friendly_date[/b] - 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?
[h2] Final notes on this method [/h2]
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: [b]o[/b] calling models to retrieve database information, [b]o[/b] setting / retrieving Session data, [b]o[/b] applying an authentication layer - often tied in with Session data, [b]o[/b] generating [url=http://www.designerevaluation.com/web-design/]Web Design[/url] [url=http://www.designerevaluation.com/logo-design/]Logo Design[/url] common view partials (headers, footers, menus).
[h2] Other Useful links [/h2]
- [url=http://en.wikipedia.org/wiki/Web_content_development]Web Content Development[/url]
- [url=http://www.seop.com/web-development/]Web Development[/url]
As an example of the last one there, have a read of Jedd's [url="/wiki/Header_and_Footer_and_Menu_on_every_page_-_jedd/"]header, footer and menu on every page[/url] article.