How to load a controller from another controller in codeigniter?
Asked Answered
H

10

39

I want to load a controller from a function in another controller because the library I integrated to my project I don't want to load it to the controller because I want to keep it clean and related.

I tried using modules but I still had to put controller in the url like

http://example.com/maincontroller/function
http://example.com/othercontroller/function

I have default controller so I can load http://example.com/function so how could I access the controller from a function from main so I don't have to put the controller in the url.

I'm still willing to use HMVC if I can load the controller function from the main controller function.

Hooky answered 4/1, 2013 at 22:17 Comment(1)
Codeigniter (and MVC in general) aren't designed to work this way. Controllers don't call other controllers. If you find yourself needing to do that it's likely an indicator that your app architecture needs some refactoring.Crocodile
H
20

you cannot call a controller method from another controller directly

my solution is to use inheritances and extend your controller from the library controller

class Controller1 extends CI_Controller {

    public function index() {
        // some codes here
    }

    public function methodA(){
        // code here
    }
}

in your controller we call it Mycontoller it will extends Controller1

include_once (dirname(__FILE__) . "/controller1.php");

class Mycontroller extends Controller1 {

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

    public function methodB(){
        // codes....
    }
}

and you can call methodA from mycontroller

http://example.com/mycontroller/methodA

http://example.com/mycontroller/methodB

this solution worked for me

Household answered 5/1, 2013 at 5:30 Comment(3)
This one is a very good alternative. Thanks for sharing it. But I have used another method to load a controller inside another controller in the old fashion way. I did not saw your answer before I used this https://mcmap.net/q/369909/-codeigniter-load-controller-within-controllerOrgandy
Using this way it will include the file controller1.php each and every time Even in those such kind of functions in which it is not required. I think better to include file in specific function rather than for all functions.Josiahjosias
@DeepKakkar can you help more on what you suggestedConstellation
I
54

yes you can (for version 2)

load like this inside your controller

 $this->load->library('../controllers/whathever');

and call the following method:

$this->whathever->functioname();
Intransigent answered 13/3, 2014 at 15:8 Comment(7)
This kind of works but if you try to load 2 controllers then things start getting wonky because of the $CI object.Evania
@Evania Could you please give a brief statement on why this is not suitable? Thanks!Madder
It gives the error message. _ Class 'CI_Template' not found in C:\xampp\htdocs\garments\system\core\Common.php on line 196_Obsessive
both of the controller is constructed with session library. After implemented your solutions, It cant load session. "Unable to locate the specified class: Session.php"Tuscan
Same issue with Mandal :-( using CI 3.xHamlen
@SaggyManateeAndSwanFolk I am having the same issue. My bet is that this answer applies to CodeIgniter 2, but not necessarily CodeIgniter 3.Detrude
True this is for version 2 not 3Intransigent
L
25

You can't load a controller from a controller in CI - unless you use HMVC or something.

You should think about your architecture a bit. If you need to call a controller method from another controller, then you should probably abstract that code out to a helper or library and call it from both controllers.

UPDATE

After reading your question again, I realize that your end goal is not necessarily HMVC, but URI manipulation. Correct me if I'm wrong, but it seems like you're trying to accomplish URLs with the first section being the method name and leave out the controller name altogether.

If this is the case, you'd get a cleaner solution by getting creative with your routes.

For a really basic example, say you have two controllers, controller1 and controller2. Controller1 has a method method_1 - and controller2 has a method method_2.

You can set up routes like this:

$route['method_1'] = "controller1/method_1";
$route['method_2'] = "controller2/method_2";

Then, you can call method 1 with a URL like http://site.com/method_1 and method 2 with http://site.com/method_2.

Albeit, this is a hard-coded, very basic, example - but it could get you to where you need to be if all you need to do is remove the controller from the URL.


You could also go with remapping your controllers.

From the docs: "If your controller contains a function named _remap(), it will always get called regardless of what your URI contains.":

public function _remap($method)
{
    if ($method == 'some_method')
    {
        $this->$method();
    }
    else
    {
        $this->default_method();
    }
}
Lockjaw answered 4/1, 2013 at 22:32 Comment(4)
Yeah, I know I can't call from another controller but with hmvc I need to use the controller in the link as I said above and because I want to keep it clean. Also, the other controller is not mine it's from another library. Do you guys think it's better to change it to a library or hmvc?Hooky
HMVC is nice and helps to structure things a bit. It depends on how often this use case may affect you. If, for just a few times, you need this, then I would say a library would be best. But, if this is something you may deal with a lot, then go ahead and add the extra bit to use HMVC. However, after reading your question again, I've updated my answer with a response to the URL issue.Lockjaw
And what one uses HMVC?Duo
@Duo HMVC is an architectural pattern - basically, it's a way to have self-contained mvc-structured modules in your application. Some others have worked out how to do that in CodeIgniter: here and hereLockjaw
H
20

you cannot call a controller method from another controller directly

my solution is to use inheritances and extend your controller from the library controller

class Controller1 extends CI_Controller {

    public function index() {
        // some codes here
    }

    public function methodA(){
        // code here
    }
}

in your controller we call it Mycontoller it will extends Controller1

include_once (dirname(__FILE__) . "/controller1.php");

class Mycontroller extends Controller1 {

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

    public function methodB(){
        // codes....
    }
}

and you can call methodA from mycontroller

http://example.com/mycontroller/methodA

http://example.com/mycontroller/methodB

this solution worked for me

Household answered 5/1, 2013 at 5:30 Comment(3)
This one is a very good alternative. Thanks for sharing it. But I have used another method to load a controller inside another controller in the old fashion way. I did not saw your answer before I used this https://mcmap.net/q/369909/-codeigniter-load-controller-within-controllerOrgandy
Using this way it will include the file controller1.php each and every time Even in those such kind of functions in which it is not required. I think better to include file in specific function rather than for all functions.Josiahjosias
@DeepKakkar can you help more on what you suggestedConstellation
W
9

I had a similar problem. I wanted to have two controllers:

homepage.php - public facing homepage

home.php - home screen once a user was logged in

and I wanted them both to read from 'mydomain.com'

I was able to accomplish this by setting 'hompepage' as the default controller in my routes config and adding a remap function to homepage.php

function _remap()
{
  if(user_is_logged_in())
  {
    require_once(APPPATH.'controllers/home.php'); 
    $oHome =  new Home();
    $oHome->index();
  }
  else
  {
    $this->index();
  }
}
Wobbling answered 24/11, 2013 at 15:37 Comment(1)
This is not advised, but can be used as one of case otherwise implement HMVC or use libraryWhacking
M
1

I was having session file not found error while tried various ways, finally achieved like this. Made the function as static (which I want to call in the another controller), and called like

require_once('Welcome.php');
Welcome::hello();
Merrifield answered 3/2, 2017 at 6:7 Comment(0)
M
1

While the methods above might work, here is a very good method.

Extend the core controller with a MY controller, then extend this MY controller for all your other controllers. For example, you could have:

class MY_Controller extends CI_Controller {
    public function is_logged()
    {
        //Your code here
    }
public function logout()
    {
        //Your code here
    }
}

Then your other controllers could then extend this as follows:

class Another_Controller extends MY_Controller {
    public function show_home()
    {
         if (!$this->is_logged()) {
           return false;
         }
    }
public function logout()
    {
        $this->logout();
    }
}
Marrin answered 4/10, 2017 at 8:59 Comment(1)
is not completed, have to put uppside: include_once (dirname(FILE) . "/MY_Controller .php");Menagerie
D
0

I came here because I needed to create a {{ render() }} function in Twig, to simulate Symfony2's behaviour. Rendering controllers from view is really cool to display independant widgets or ajax-reloadable stuffs.

Even if you're not a Twig user, you can still take this helper and use it as you want in your views to render a controller, using <?php echo twig_render('welcome/index', $param1, $param2, $_); ?>. This will echo everything your controller outputted.

Here it is:

helpers/twig_helper.php

<?php

if (!function_exists('twig_render'))
{

    function twig_render()
    {
        $args = func_get_args();
        $route = array_shift($args);
        $controller = APPPATH . 'controllers/' . substr($route, 0, strrpos($route, '/'));

        $explode = explode('/', $route);
        if (count($explode) < 2)
        {
            show_error("twig_render: A twig route is made from format: path/to/controller/action.");
        }

        if (!is_file($controller . '.php'))
        {
            show_error("twig_render: Controller not found: {$controller}");
        }
        if (!is_readable($controller . '.php'))
        {
            show_error("twig_render: Controller not readable: {$controller}");
        }
        require_once($controller . '.php');

        $class = ucfirst(reset(array_slice($explode, count($explode) - 2, 1)));
        if (!class_exists($class))
        {
            show_error("twig_render: Controller file exists, but class not found inside: {$class}");
        }

        $object = new $class();
        if (!($object instanceof CI_Controller))
        {
            show_error("twig_render: Class {$class} is not an instance of CI_Controller");
        }

        $method = $explode[count($explode) - 1];
        if (!method_exists($object, $method))
        {
            show_error("twig_render: Controller method not found: {$method}");
        }

        if (!is_callable(array($object, $method)))
        {
            show_error("twig_render: Controller method not visible: {$method}");
        }

        call_user_func_array(array($object, $method), $args);

        $ci = &get_instance();
        return $ci->output->get_output();
    }

}

Specific for Twig users (adapt this code to your Twig implementation):

libraries/Twig.php

$this->_twig_env->addFunction('render', new Twig_Function_Function('twig_render'));

Usage

{{ render('welcome/index', param1, param2, ...) }}
Discrown answered 17/4, 2014 at 17:19 Comment(0)
K
0

Create a helper using the code I created belows and name it controller_helper.php.

Autoload your helper in the autoload.php file under config.

From your method call controller('name') to load the controller.

Note that name is the filename of the controller.

This method will append '_controller' to your controller 'name'. To call a method in the controller just run $this->name_controller->method(); after you load the controller as described above.

<?php

if(!function_exists('controller'))
{
    function controller($name)
    {
        $filename = realpath(__dir__ . '/../controllers/'.$name.'.php');

        if(file_exists($filename))
        {
            require_once $filename;

            $class = ucfirst($name);

            if(class_exists($class))
            {
                $ci =& get_instance();

                if(!isset($ci->{$name.'_controller'}))
                {
                    $ci->{$name.'_controller'} = new $class();
                }
            }
        }
    }
}
?>
Kief answered 30/11, 2016 at 2:51 Comment(0)
D
0

There are many ways by which you can access one controller into another.

class Test1 extends CI_controller
{
    function testfunction(){
        return 1;
    }
}

Then create another class, and include first Class in it, and extend it with your class.

include 'Test1.php';

class Test extends Test1
{
    function myfunction(){
        $this->test();
        echo 1;
    }
}
Domini answered 10/1, 2020 at 5:18 Comment(0)
C
0

You can call Model from a Controller so put your functions inside a Model and call it from the controller . Worked for me. (codeignitor 3)

Cholecystectomy answered 12/3, 2022 at 4:38 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Charlet

© 2022 - 2024 — McMap. All rights reserved.