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的设置和处理冲突。