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

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

如何从home控制器的index操作中访问product信息? 实例化product将无法运行,因为该类在运行时未加载,CodeIgniter不提供dynamic加载控制器的方法。 把product类放到一个库文件中也不行。

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

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

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

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

好的,所以现在最大的变化就是你会使用模块化结构 – 但对我来说这是可取的。 我已经使用CI大约3年了,不能想象没有模块化扩展的生活。

现在,下面是处理直接调用控制器渲染视图部分的部分:

 // 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); ?> 

这就是它的全部。 我通常使用这个加载一些“小部件”,如:

  • 活动日历
  • 最新的新闻文章列表
  • 通讯registry格
  • 民意调查

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

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

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

像这样加载它

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

并调用以下方法:

 $this->instructor->functioname() 

这适用于CodeIgniter 2.x。

只是为了增加更多的信息扎恩·阿巴斯说:

用这种方式加载控制器,像他说的那样使用它:

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

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

 $this->load->library('../controllers/your_controller'); $obj = new $this->your_controller(); $obj->your_function(); 

希望这可以帮助。

在这种情况下,你可以尝试一些老派的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); } } 

然后只要你喜欢使用控制器的方法。

基于@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的情况下在另一个控制器内加载控制器。

稍后编辑:请注意,此方法可能会有意想不到的结果。 总是testing它!

在控制器内部加载控制器有很多很好的答案,但对我来说,这与mvc模式相矛盾。

我担心的是

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

这些模型用于处理和返回数据。 如果你把这个逻辑放到你的产品模型中,那么你可以从你喜欢的任何一个控制器调用它,而不必试图歪曲框架。

我读过的最有用的引用之一是,控制器就像“交通警察”,在那里发送模型和视图之间的请求和响应。

只是使用

…………..

self::index();

…………..

用下面的代码你可以加载控制器类并执行这些方法。

此代码是为codeigniter 2.1编写的

首先在您的应用程序/核心目录中添加一个新文件MY_Loader.php 。 将下面的代码添加到新创build的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); } } 

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

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

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

或者当class级在一个目录中时

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

它只是像加载模型一样工作

根据这个博客文章,你可以加载控制器在另一个控制器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); } } } 

然后将控制器载入另一个控制器

我知道这是旧的,但任何人都应该find它最近,我会build议在控制器文件夹中创build一个单独的类文件。 将现有的控制器对象传入类构造函数,然后可以从任何地方访问函数,而不会与CI的设置和处理冲突。