user6655274
user6655274

Reputation:

Extending and extended class in CodeIgniter 3

I have a controller "MY_Controller.php" in "application/core" that extends "CI_Controller":

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class MY_Controller extends CI_Controller
{

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

        $this->load->helper('form');
        $this->load->helper('url');
        $this->load->helper('security');
        $this->load->helper('language');

        // Load language file
        $this->lang->load('en_admin', 'english');

    }

}

I created another controller called "Auth.php" in "application/controllers" that extends "MY_Controller":

class Auth extends MY_Controller
{

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

        $this->load->library('ion_auth');

        if ($this->ion_auth->logged_in() === FALSE) {

            redirect('user/login');

        }
    }
}

I created a third controller "Dashboard.php" that should extend "Auth", but throws an error:

class Dashboard extends Auth
{
    public function index()
    {
        echo 'Hello from the dashboard';
    }
}

Fatal error: Class 'Auth' not found in /home/user/www/forum/application/controllers/Dashboard.php on line 5

Would appreciate your advice to solve this problem.

Upvotes: 1

Views: 3093

Answers (3)

TimBrownlaw
TimBrownlaw

Reputation: 5507

Well I've never used MY_Controller. I specify my class names.

I create all my classes under application/libraries and my structure is

Admin extends Common_Controller Common_Controller handles the auth stuff for admin and members login/auth etc Admin is a Controller up in application/modules/admin/controllers/Admin.php

Common_Controller extends Base_Controller Base_Controller handles all the stuff common to all controllers like the templating etc

Base_Controller extends MX_Controller MX_Controller is the wiredesignz HMVC Controller

MX_Controller extends CI_Controller and we are done.

This is of course a HMVC setup but the principle is the same. Just don't use MY_Controller, give it a real name and use it normally.

And of course HMVC uses MY_Loader and other classes MY_xxx it uses to hook itself into CI and they live under application/core and it all plays nicely.

So as far as I can tell, there isn't a limit on how many classes deep you can go when you are extending them.

Upvotes: 0

Greg Kelesidis
Greg Kelesidis

Reputation: 1054

This is the regular behavior. Controllers do not extend each other. They may only extend MY_Controller (or CI_Controller). This is true for all MVC frameworks.
The way to use ion_auth, is not to extend Auth controller. You have already loaded ion_auth library, so you may directly use its methods in all controllers, the same way you use them in Auth controller. Documentation for ion_auth here.

Upvotes: 0

DFriend
DFriend

Reputation: 8964

The link in my comment has multiple ways to solve your problem. I prefer to use the #3 method - "Using an autoload function with hooks". Here's what works for me.

application/config/config.php

$config['enable_hooks'] = TRUE;

application/config/hooks.php

$hook['pre_system'][] = array(
  'class' => '',
  'function' => 'register_autoloader',
  'filename' => 'Auto_load.php',
  'filepath' => 'hooks'
);

application/hooks/Auto_load.php

<?php
    defined('BASEPATH') OR exit('No direct script access allowed');

    function register_autoloader()
    {
      spl_autoload_register('site_autoloader');
    }

    /*
     * Custom autoloader.
     * This piece of code will allow controllers and other classes 
     * that do not start with "CI_" to be loaded when  
     * extending controllers, models, and libraries.
     */
    function site_autoloader($class)
    {
        if(strpos($class, 'CI_') !== 0)
        {
            if(file_exists($file = APPPATH.'core/'.$class.'.php'))
            {
                require_once $file;
            }
            elseif(file_exists($file = APPPATH.'libraries/'.$class.'.php'))
            {
                require_once $file;
            }
            elseif(file_exists($file = APPPATH.'models/'.$class.'.php'))
            {
                require_once $file;
            }
        }
    }

Your first extend of CI_Controller - class MY_Controller extends CI_Controller - should probably be in application/core/MY_Controller.php. Any classes that extend MY_Controller should be in application/libraries/.

The linked page labels the "hook" method as "the slow and right way" but the profiling I did comparing it to "2. Using an autoload function (the fast and dirty way)" showed a time difference of slightly over a microsecond. That's not worth worrying about.

I used the "fast and dirty way" for many years but kept forgetting about it when upgrading CI and I'd overwrite the config file resulting in a lost autoloader routine. Don't have that problem using the hook method other than remembering to set $config['enable_hooks'] to TRUE.

Upvotes: 0

Related Questions