CodeIgniter:在控制器中加载控制器
Posted
技术标签:
【中文标题】CodeIgniter:在控制器中加载控制器【英文标题】:CodeIgniter: Load controller within controller 【发布时间】:2011-08-30 18:30:18 【问题描述】:我有一个带有index
操作的home
控制器,它显示一组特色产品。但是,产品是通过 product
控制器管理的,包括专有模型和视图。
如何从home
控制器的index
操作中访问product
信息?实例化product
将不起作用,因为在运行时未加载该类,并且 CodeIgniter 不提供动态加载控制器的方法。将product
类放入库文件中也不起作用。
确切地说,我需要将产品视图(填充由product
控制器处理的数据)插入到索引视图中。我正在运行 CodeIgniter 2.0.2。
【问题讨论】:
看起来您正在使用控制器来详细说明数据。我建议你为此使用模型,这样你就必须独立于你所在的控制器调用模型的方法(MVC'skinny controller,fat model') 我更愿意谈论小部件或部分——我希望有一致的模块可以放入站点模板中。这或多或少需要实例化控制器。 【参考方案1】:像这样加载它
$this->load->library('../controllers/instructor');
并调用以下方法:
$this->instructor->functioname()
这适用于 CodeIgniter 2.x。
【讨论】:
谢谢。请注意,CodeIgniter 将控制器视为单例,因此我发现一旦加载另一个控制器,您的原始控制器将不再正常工作。加载其他控制器后,请确保不要尝试使用$this->load
或原始控制器中的任何已加载模型;而是使用$ci = get_instance()
并仅通过$ci
访问模型(例如$ci->user_model
)。
即使在您的评论旁边,原始控制器也可以正常工作。
加 1 虽然我不知道教练实际上是控制器
这个只能调用一次。如果你尝试调用另一个控制器,你会得到一个Undefined property
。
这对我来说是最好的答案【参考方案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); ?>
仅此而已。我通常使用它来加载小“小部件”,例如:
活动日历 最新新闻文章列表 时事通讯注册表单 投票通常我为每个模块构建一个“小部件”控制器,并仅将其用于此目的。
【讨论】:
【参考方案3】:在这种情况下,您可以尝试一些老式的 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】:只是想为 Zain Abbas 所说的话添加更多信息:
以这种方式加载控制器,然后像他说的那样使用它:
$this->load->library('../controllers/instructor');
$this->instructor->functioname();
或者您可以创建一个对象并以这种方式使用它:
$this->load->library('../controllers/your_controller');
$obj = new $this->your_controller();
$obj->your_function();
【讨论】:
您好,此解决方案适用于 CI 2.x。似乎 CI 3.x 不再允许这样做,现在我不使用 CI 3.x,所以我帮不了你太多。检查这个论坛forum.codeigniter.com/thread-744-page-2.html也许你可以在那里得到一些信息。这是一个github问题,可能与您的问题github.com/bcit-ci/CodeIgniter/issues/3480有关。【参考方案5】:根据@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 的情况下将控制器加载到另一个控制器中。
稍后编辑:请注意,此方法可能会产生意想不到的结果。总是测试它!
【讨论】:
【参考方案6】:使用以下代码,您可以加载控制器类并执行方法。
此代码是为 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();
或者当类在目录中时
$this->load->controller('/dir/invoice','invoice_controller');
$this->invoice_controller->test();
它就像加载模型一样工作
【讨论】:
【参考方案7】:根据这篇博文,您可以在 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);
然后在另一个控制器中加载控制器。
【讨论】:
【参考方案8】:对于在控制器中加载控制器,这里给出了很多很好的答案,但对我来说,这与 mvc 模式相矛盾。
让我担心的一句话是;
(填充产品控制者处理的数据)
模型用于处理和返回数据。如果您将此逻辑放入您的产品模型中,那么您可以从您喜欢的任何控制器调用它,而无需尝试破坏框架。
我读到的最有帮助的一句话是,控制器就像“交通警察”,负责在模型和视图之间路由请求和响应。
【讨论】:
【参考方案9】:我知道这是旧的,但如果最近有人发现它,我建议在控制器文件夹中创建一个单独的类文件。将现有的控制器对象传入类构造函数中,然后您可以从任何地方访问这些函数,并且不会与 CI 的设置和处理冲突。
【讨论】:
【参考方案10】:你可以用这个:
self::index();
【讨论】:
以上是关于CodeIgniter:在控制器中加载控制器的主要内容,如果未能解决你的问题,请参考以下文章
我如何在控制器函数中加载目录作为视图:Codeigniter
在 codeigniter 的控制器中加载模型时出错消息:未定义的属性:Cart::$load