20

I have class MY_Controller extends CI_Controller and common logic for big profile section, so I'va tried to create class Profile extends MY_Controller with common logic for profile section and all class related to this section should extends this Profile class as I understand right, but when I tried to create class Index extends Profile I recieve an error:

Fatal error: Class 'Profile' not found

CodeIgniter tries to find this class in index.php which I am running.

Where is my mistake? Or maybe there is anoter better way to mark out common logic?

Yekver
  • 4,985
  • 7
  • 32
  • 49
  • I asked the same question [here][1] [1]: http://stackoverflow.com/questions/7982187/codeigniter-extending-common-controller Hope it helps – luso Dec 01 '11 at 14:36

5 Answers5

29

I take it you have put your MY_Controller in /application/core, and set the prefix in the config. I would be careful about using index as a class name though. As a function/method in Codeigniter it has a dedicated behaviour.

If you then want to extend that controller you need to put the classes in the same file.

E.g. In /application core

/* start of php file */
class MY_Controller extends CI_Controller {
    public function __construct() {
       parent::__construct();
    }
...
}

class another_controller extends MY_Controller {
    public function __construct() {
       parent::__construct();
    }
...
}
/* end of php file */

In /application/controllers

class foo extends MY_Controller {
    public function __construct() {
       parent::__construct();
    }
...
}

or

class bar extends another_controller {
    public function __construct() {
       parent::__construct();
    }
...
}
Rooneyl
  • 7,802
  • 6
  • 52
  • 81
  • Probably worth mentioning that methods in `MY_Controller` should _likely_ be prefixed with `_`, so that CI doesn't route them (since, by nature all methods you want to share with all controllers must be public). – Tim Post Apr 29 '12 at 15:37
  • 7
    Surely the shared methods can be protected instead of public. So they won't get routed, but will be accessible by the extending controllers. – manavo Sep 17 '12 at 13:51
5

I found this page on Google because I had the same problem. I didn't like the answers listed here so I created my own solution.

1) Place your parent class in the core folder.

2) Place an include statement at the beginning of all classes that include the parent class.

So a typical controller might look like this:

<?php

require_once APPPATH . 'core/Your_Base_Class.php';
// must use require_once instead of include or you will get an error when loading 404 pages

class NormalController extends Your_Base_Class
{
    public function __construct()
    {
        parent::__construct();

        // authentication/permissions code, or whatever you want to put here
    }

    // your methods go here
}

The reason I like this solution is, the whole point of creating a parent class is to cut down on code repetition. So I don't like the other answer that suggested copy/pasting the parent class into all of your controller classes.

RedDragonWebDesign
  • 1,797
  • 2
  • 18
  • 24
5

It is possible with Codeigniter 3. Just including the parent file is enough.

require_once(APPPATH."controllers/MyParentController.php");
class MyChildController extends MyParentController {
...
Cem Yıldız
  • 122
  • 1
  • 5
0

All classes you are extending should live in application/CORE directory so in your case both My_Controller and Profile should live there. All "end point" controllers will live in application/controllers folder

UPDATE

I stand corrected. Extended classes should live in the same file. @Rooneyl's answer shows how to implement

Alexey Gerasimov
  • 2,131
  • 13
  • 17
  • I think is not necesary that all the controllers are under CORE but only the base controllers. – luso Dec 01 '11 at 14:41
  • @luso, I tried putting my_controllers in /controllers/core and Profile & OtherClass (op called it Index) in /controllers. Otherclass extends Profile extends My_controller. that throws error. Move Profile to /core and it works. Are you able to put Profile & OtherClass in /controllers and get it to work? – Alexey Gerasimov Dec 01 '11 at 14:47
  • @Alexey Gerasimov I've moved Profile class to the application/core folder, but nothing have changed. I do recieve the same error. Does it matter what name have file or anything else? What have I missed? – Yekver Dec 01 '11 at 14:57
  • take a look at http://stackoverflow.com/questions/7627587/code-igniter-2-how-to-extend-ci-controller-multiple-times/7627642#7627642 and http://philsturgeon.co.uk/blog/2010/02/CodeIgniter-Base-Classes-Keeping-it-DRY – Rooneyl Dec 01 '11 at 15:01
  • @Rooneyl I got it. But is it a good practise to create an `__autoload` function, or better place all common classes in MY_Controller? – Yekver Dec 01 '11 at 15:18
  • @Yekver Just me me, I tend to extend the core files in the way I described. Autoload in on the way out (http://php.net/manual/en/language.oop5.autoload.php), and I don't want to redo things. I'm too lazy! – Rooneyl Dec 01 '11 at 15:24
  • is not app/controllers/core but /app/core – luso Dec 01 '11 at 15:34
-1

After some struggle with version 3 and this issue I decided this was not a bad solution...

require_once BASEPATH.'core/Controller.php';
require_once APPPATH.'core/MYCI_Controller.php';

to add this second line where the first exists in the system/core/CodeIgniter.php

[If it's not too late, I recommend strongly against php and/or CodeIgniter.]

Master James
  • 1,691
  • 15
  • 19