CodeIgniter:在控制器内加载控制器

时间:2011-05-22 22:00:13

标签: php codeigniter

我有一个home控制器,其index动作显示一组特色产品。但是,产品通过product控制器进行管理,包括专有模型和视图。

如何从product控制器中的index操作中访问home个信息?实例化product将不起作用,因为类未在运行时加载,并且CodeIgniter不提供动态加载控制器的方法。将product类放入库文件中也不起作用。

确切地说,我需要在索引视图中插入产品视图(填充由product控制器处理的数据)。我正在运行CodeIgniter 2.0.2。

10 个答案:

答案 0 :(得分:63)

像这样加载

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

并调用以下方法:

$this->instructor->functioname()

适用于CodeIgniter 2.x

答案 1 :(得分:30)

如果您有兴趣,那里有一个完善的软件包,您可以添加到您的Codeigniter项目中来处理这个问题:

https://bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc/

  

Modular Extensions 使CodeIgniter PHP框架模块化。模块是一组独立的组件,通常是模型,控制器和视图,安排在应用程序模块子目录中,可以放入其他CodeIgniter应用程序中。

好的,所以最大的变化就是现在你正在使用模块化结构 - 但对我来说这是可取的。我已经使用CI大约3年了,并且无法想象没有Modular Extensions的生活。

现在,这是处理直接调用控制器以呈现视图部分的部分:

// Using a Module as a view partial from within a view is as easy as writing:
<?php echo modules::run('module/controller/method', $param1, $params2); ?>

这就是它的全部。我通常使用它来加载像“小部件”这样的小部件:

  • 活动日历
  • 最新新闻文章列表
  • 简报注册表格
  • 投票

通常我会为每个模块构建一个“小部件”控制器,并仅将其用于此目的。

当我开始使用Codeigniter时,您的问题也是我的第一个问题。我希望这可以帮助你,即使它可能比你想要的多一点。从那时起我一直在使用MX,并且没有回头。

请务必阅读文档,并在Codeigniter论坛上查看有关此软件包的大量信息。享受!

答案 2 :(得分:8)

只是为了补充Zain Abbas所说的更多信息:

以这种方式加载控制器,并按照他说的那样使用它:

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

$this->instructor->functioname();

或者您可以创建一个对象并以这种方式使用它:

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

$obj = new $this->your_controller();

$obj->your_function();

希望这可以提供帮助。

答案 3 :(得分:7)

在这种情况下,你可以尝试一些旧学校的PHP。

// insert at the beggining of home.php controller require_once(dirname(__FILE__)."/product.php"); // the controller route.

然后,你会有类似的东西:

Class Home extends CI_Controller
{
 public function __construct()
 {
  parent::__construct();
  $this->product = new Product();
  ...
 }

 ...
 // usage example
 public function addProduct($data)
 {
  $this->product->add($data);
 }
}

然后根据需要使用控制器的方法。

答案 4 :(得分:6)

根据@Joaquin Astelarra的回复,我设法写了这个名为 load_controller_helper.php 的小助手:

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

if (!function_exists('load_controller'))
{
    function load_controller($controller, $method = 'index')
    {
        require_once(FCPATH . APPPATH . 'controllers/' . $controller . '.php');

        $controller = new $controller();

        return $controller->$method();
    }
}

您可以像这样使用/调用它:

$this->load->helper('load_controller');
load_controller('homepage', 'not_found');

注意:第二个参数不是必需的,因为它将运行名为 index 的方法,就像CodeIgniter那样。

现在,您可以在不使用HMVC的情况下在另一个控制器内加载控制器。

稍后编辑:请注意,此方法可能会产生意外结果。总是测试它!

答案 5 :(得分:1)

这里有很多很好的答案可以在控制器中加载控制器,但对我而言,这与mvc模式相矛盾。

让我担心的一句话是;

  

(填充产品控制器处理的数据)

模型用于处理和返回数据。如果您将此逻辑放入产品模型中,则可以从任何您喜欢的控制器中调用它,而不必尝试阻止框架。

我读到的最有用的引用之一就是控制器就像“交通警察”,它可以在模型和视图之间路由请求和响应。

答案 6 :(得分:0)

使用以下代码,您可以加载控制器类并执行方法。

此代码是为codeigniter 2.1

编写的

首先在您的应用程序/核心目录中添加一个新文件MY_Loader.php。将以下代码添加到新创建的MY_Loader.php文件中:

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

// written by AJ  sirderno@yahoo.com

class MY_Loader extends CI_Loader 
{
    protected $_my_controller_paths     = array();  

    protected $_my_controllers          = array();


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

        $this->_my_controller_paths = array(APPPATH);
    }

    public function controller($controller, $name = '', $db_conn = FALSE)
    {
        if (is_array($controller))
        {
            foreach ($controller as $babe)
            {
                $this->controller($babe);
            }
            return;
        }

        if ($controller == '')
        {
            return;
        }

        $path = '';

        // Is the controller in a sub-folder? If so, parse out the filename and path.
        if (($last_slash = strrpos($controller, '/')) !== FALSE)
        {
            // The path is in front of the last slash
            $path = substr($controller, 0, $last_slash + 1);

            // And the controller name behind it
            $controller = substr($controller, $last_slash + 1);
        }

        if ($name == '')
        {
            $name = $controller;
        }

        if (in_array($name, $this->_my_controllers, TRUE))
        {
            return;
        }

        $CI =& get_instance();
        if (isset($CI->$name))
        {
            show_error('The controller name you are loading is the name of a resource that is already being used: '.$name);
        }

        $controller = strtolower($controller);

        foreach ($this->_my_controller_paths as $mod_path)
        {
            if ( ! file_exists($mod_path.'controllers/'.$path.$controller.'.php'))
            {
                continue;
            }

            if ($db_conn !== FALSE AND ! class_exists('CI_DB'))
            {
                if ($db_conn === TRUE)
                {
                    $db_conn = '';
                }

                $CI->load->database($db_conn, FALSE, TRUE);
            }

            if ( ! class_exists('CI_Controller'))
            {
                load_class('Controller', 'core');
            }

            require_once($mod_path.'controllers/'.$path.$controller.'.php');

            $controller = ucfirst($controller);

            $CI->$name = new $controller();

            $this->_my_controllers[] = $name;
            return;
        }

        // couldn't find the controller
        show_error('Unable to locate the controller you have specified: '.$controller);
    }

}

现在您可以加载应用程序/控制器目录中的所有控制器。 例如:

加载控制器类Invoice并执行函数test()

$this->load->controller('invoice','invoice_controller');

$this->invoice_controller->test();

或当班级在dir内时

$this->load->controller('/dir/invoice','invoice_controller');

$this->invoice_controller->test();

它的工作原理与加载模型

相同

答案 7 :(得分:0)

只需使用

..............

self::index();

..............

答案 8 :(得分:0)

根据这篇博客文章,您可以在codeigniter中的另一个控制器中加载控制器。

http://www.techsirius.com/2013/01/load-controller-within-another.html

首先,您需要扩展CI_Loader

<?php

class MY_Loader extends CI_Loader {

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

    public function controller($file_name) {
        $CI = & get_instance();
        $file_path = APPPATH.'controllers/' . $file_name . '.php';
        $object_name = $file_name;
        $class_name = ucfirst($file_name);

        if (file_exists($file_path)) {
            require $file_path;

            $CI->$object_name = new $class_name();
        }
        else {
            show_error('Unable to load the requested controller class: ' . $class_name);
        }
    }
}

然后在另一个控制器内加载控制器。

答案 9 :(得分:0)

我知道这是旧的,但是如果有人最近发现它,我建议在controllers文件夹中创建一个单独的类文件。将现有的控制器对象传递给类构造函数,然后您可以从任何地方访问这些函数,它不会与CI的设置和处理冲突。