2011-05-22 86 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的設置和處理髮生衝突。