2011-05-22 81 views
42

我有一个home控制器,其中index动作显示一组特色产品。但是,产品通过包含专有模型和视图的控制器进行管理。CodeIgniter:控制器内的负载控制器

如何在home控制器的index动作中访问product信息?实例product不会工作,因为该类未在运行时加载,并且CodeIgniter不提供动态加载控制器的方法。将product类放到一个库文件中也没有效果。准确地说,我需要在索引视图中插入产品视图(填充由product控制器处理的数据)。我正在运行CodeIgniter 2.0.2。

+4

看起来您正在使用控制器来制作数据。我建议你使用模型,这样你就可以独立于你所在的控制器调用模型的方法(MVC'瘦身控制器,胖模型') – 2011-05-22 22:04:44

+0

我更喜欢讨论部件或部件 - 我很想拥有一致的模块来放置网站模板。这或多或少需要实例化控制器。 – Daniel 2011-05-22 22:53:10

回答

30

如果你有兴趣,有一个完善的包在那里,你可以添加到您的笨项目,将处理这个问题:

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

模块化扩展使笨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); ?> 

这一切就是这么简单。我通常使用这种加载有点“小工具”,如:

  • 事件日历
  • 列表最新的新闻文章的
  • 注册简报形式
  • 投票

通常我建立一个“窗口小部件“每个模块的控制器并仅用于此目的。

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

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

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); 
} 
} 

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

0

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

此代码是为笨2.1书面

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

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

// written by AJ [email protected] 

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); 
    } 

} 

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

负载控制器类发票并执行功能测试()

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

$this->invoice_controller->test(); 

,或者当类内的DIR

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

$this->invoice_controller->test(); 

这只是工作相同等装载型号

62

像这样加载

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

,并调用下面的方法:

$this->instructor->functioname() 

这适用于笨2.X

+3

那里最好的解决方案 – Umren 2013-04-14 12:22:44

+3

谢谢你。请注意,CodeIgniter将控制器视为单例,因此我发现一旦加载其他控制器,原始控制器将不再正常工作。加载其他控制器后,确保不要尝试使用'$ this-> load'或原始控制器中的任何加载模型;而是使用'$ ci = get_instance()'并且只能通过'$ ci'(例如'$ ci-> user_model')访问模型。 – 2013-08-15 21:03:42

+0

即使在您的评论旁边,原始控制器也能正常工作。 – 2013-08-17 15:32:42

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'); 

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

现在,您将能够在不使用HMVC的情况下将控制器加载到另一个控制器中。

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

8

只是为了更多信息添加到什么萨恩·阿巴斯说:

装入控制器的方式,并使用它像他说:

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

$this->instructor->functioname(); 

或者你可以创建一个对象并以此方式使用它:

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

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

$obj->your_function(); 

希望这可以帮助。

+0

CI 3.x中不再工作mawma – 2016-09-03 14:55:11

+1

嗨,这个解决方案是为CI 2.x的似乎CI 3.x不再允许这样做,现在我不使用CI 3.x,所以我无法帮助你。检查这个论坛http://forum.codeigniter.com/thread-744-page-2.html也许你可以在那里得到一些信息。这里是一个github问题,也许与你的问题有关https://github.com/bcit-ci/CodeIgniter/issues/3480。 – 2016-09-05 08:37:47

0

只需使用

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

self::index();

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

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); 
     } 
    } 
} 

然后负载控制器的第一。

1

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

担心我的句子是;

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

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

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

0

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