我有一个home
控制器,其index
动作显示一组特色产品。但是,产品通过product
控制器进行管理,包括专有模型和视图。
如何从product
控制器中的index
操作中访问home
个信息?实例化product
将不起作用,因为类未在运行时加载,并且CodeIgniter不提供动态加载控制器的方法。将product
类放入库文件中也不起作用。
确切地说,我需要在索引视图中插入产品视图(填充由product
控制器处理的数据)。我正在运行CodeIgniter 2.0.2。
答案 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的设置和处理冲突。