27

I have successfully extended the CI_Controller class by creating a MY_Controller.php which I have placed in the application/core directory.

core/My_Controller.php looks something like this:

class MY_Controller extends CI_Controller {

    function __construct()
    {
        parent::__construct();
    }
}

Then when I create normal controllers they look something like this:

class Home extends MY_Controller {

    function __construct()
    {
        parent::__construct();
    }

    function index()
    {
        $this->load->view('home');
    }
}

I'm creating a admin back end and I want to have a different base class for controllers to extend instead of My_Controller. This is so I can have common methods for the admin controllers (i.e. authentication_check etc.)

What I can't work out is how I create another controller that extends CI_Controller.

The goal is for admin controllers to extend a different base class than the front-end controllers.

The admin base controller would look like this:

class MY_Admin_Controller extends CI_Controller {

    function __construct()
    {
        parent::__construct();
    }
}

An normal controller for admin pages:

class Admin_home extends MY_Admin_Controller {

    function __construct()
    {
        parent::__construct();
    }

    function index()
    {
        $this->load->view('admin_home');
    }
}

The problem is that to extend the CI_Controller class you must name your controller file PREFIX_Controller.php and place it in the core/ directory. But I want two controller classes and they can't have the same filename.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Camsoft
  • 11,718
  • 19
  • 83
  • 120

5 Answers5

29

You just put both in the same file, I have a project that is exactly the same as this.

We just have both the admin and normal extended controller in the MY_Controller.php file, works fine.

The main reason for the MY_Controller or other extended files is so that CodeIgniter auto initiates them when you load the base file (whether library, helper, etc.), you can have many classes in these files.

Edit:

You don't even need to call them MY_Admin_Controller or MY_Controller, we have Admin_Controller and User_Controller and Ajax_Controller in the MY_Controller File

Cubed Eye
  • 5,581
  • 4
  • 48
  • 64
  • 14
    But that's quite soiling the framework, and going against their purpose of cleaner coding and architecture...It smells bad. – Damien Pirsy Oct 02 '11 at 16:34
  • 2
    I'm not sure where on the forums I read it, but that's how it was suggested to do it when I first started using CodeIgniter, if the suggested method has changed then let me know – Cubed Eye Oct 02 '11 at 16:36
  • If it works, doesn't mean it is the right thing to do.Just givin my opinion though, I don't have better answers. – Damien Pirsy Oct 02 '11 at 16:44
  • 2
    It's not soiling the framework, but make use of it's include/loading mechanism. As an alternative, you can provide an autoloader of your own and just place a blank file in there. – hakre Oct 02 '11 at 16:48
  • 1
    @DamienPirsy Can you explain why you think it's bad? Is this not the entire point of OO? If there is common code that all my view controllers need why not put that code in a super class and extend that? – Camsoft Oct 02 '11 at 21:39
  • 1
    @Camsoft, well IMHO the problem with the solution is that you've got 2 controllers in one file, so it becomes less obvious as to how the system works to an outsider. Swatkin's solution seems much nicer to me :) – Algy Taylor Jan 14 '14 at 11:27
  • Also it is possible to define separate parent controllers like "MY_Admin_Controller.php" in different file(s) by simply including them in "MY_Controller.php". – Mojtaba Rezaeian Jun 01 '15 at 09:03
17

What you're doing is correct. You just need all of these files in the application/core directory. Here's a post by Phil Sturgeon regarding just this:

http://philsturgeon.co.uk/blog/2010/02/CodeIgniter-Base-Classes-Keeping-it-DRY
http://philsturgeon.uk/blog/2010/02/CodeIgniter-Base-Classes-Keeping-it-DRY/

The trick is to use the __autoload() function - which Phil describes in his post.

Mohammad Faisal
  • 5,783
  • 15
  • 70
  • 117
swatkins
  • 13,530
  • 4
  • 46
  • 78
  • 2
    If you use the linked example, just remember the `@` error suppression will also suppress syntax errors in the class file causing a silent fail. – Seain Malkin Dec 21 '13 at 22:47
3

This is pretty easy. Do the following:

  1. Go to the following directory: your_ci_app/application/core/ and create a php file called MY_Controller.php (this file will be where your top parent classes will reside)
  2. Open this the file you just created and add your multiple classes, like so:

    class Admin_Parent extends CI_Controller {
        public function __construct() {
            parent::__construct();
        }
    
        public function test() {
            var_dump("from Admin_Parent");
        }
    }
    
    class User_Parent extends CI_Controller {
    
        public function __construct() {
            parent::__construct();
        }
    
        public function test(){
            var_dump("from User_Parent");
        }
    
    }
    
  3. Create your children controllers under this directory your_ci_app/application/controllers/ . I will call it adminchild.php

  4. Open adminchild.php and create your controller code, make sure to extend the name of the parent class, like so:

    class Adminchild extends Admin_Parent {
    
        function __construct() {
            parent::__construct();
        }
    
        function test() {
            parent::test();
        }
    
    }
    
CodeGodie
  • 12,116
  • 6
  • 37
  • 66
1

if you want to extend another class instead of CI_controller you must include the target class. for example

include 'auth.php';

class test extends Auth
Saman Salehi
  • 1,004
  • 1
  • 12
  • 19
0

All files in the folder application/core


MY is subclass CI
MY have 2 subclasses Public and Dashboard
class MY_Controller extends CI_Controller
{
    public function __construct()
    {
        parent::__construct();

        echo "This is " . __CLASS__ . "<br />";
    }
}

Public

class Public_Controller extends My_Controller
{
    public function __construct()
    {
        parent::__construct();

        echo "This is " . __CLASS__ . "<br />";
    }
}

Dashboard have 2 subclasses, Admin and User

class Dashboard_Controller extends My_Controller
{
    public function __construct()
    {
        parent::__construct();

        echo "This is " . __CLASS__ . "<br />";
    }
}

Admin

class Admin_Controller extends Dashboard_Controller
{
    public function __construct()
    {
        parent::__construct();

        echo "This is " . __CLASS__ . "<br />";
    }
}

User

class User_Controller extends Dashboard_Controller
{
    public function __construct()
    {
        parent::__construct();

        echo "This is " . __CLASS__ . "<br />";
    }
}

in config/config.php

/* load class in core folder */
function my_load($class) {        
    if (strpos($class, 'CI_') !== 0) {            
        if (is_readable(APPPATH . 'core' . DIRECTORY_SEPARATOR . $class . '.php' )) {                
            require_once (APPPATH . 'core' . DIRECTORY_SEPARATOR . $class . '.php');                
        }
    }        
}

spl_autoload_register('my_load');

in controller/Home.php

//class Home extends MY_Controller {
//class Home extends Dashboard_Controller {
class Home extends Admin_Controller {

    public function index()
    {
        echo "This is " . __CLASS__ . "<br />";
        //$this->load->view('home');
    }
}
antelove
  • 3,216
  • 26
  • 20