簡體   English   中英

如何在codeigniter中從另一個controller加載一個controller?

[英]How to load a controller from another controller in codeigniter?

我想從另一個 controller 中的 function 加載一個 controller 因為我集成到我的項目的庫我不想將它加載到 controller 因為我想保持它的清潔和相關。

我嘗試使用模塊,但我仍然不得不將 controller 放在 url 之類的

http://example.com/maincontroller/function
http://example.com/othercontroller/function

我有默認的 controller 所以我可以加載http://example.com/function所以我怎么能從 function 從 main 訪問 controller 所以我不必把 controller 放在 url.

如果我可以從主 controller function 加載 controller function,我仍然願意使用 HMVC。

是的,你可以(對於版本 2)

在您的控制器中像這樣加載

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

並調用以下方法:

$this->whathever->functioname();

你不能從 CI 中的控制器加載控制器 - 除非你使用 HMVC 或其他東西。

您應該稍微考慮一下您的架構。 如果您需要從另一個控制器調用控制器方法,那么您可能應該將該代碼抽象為幫助程序或庫,並從兩個控制器調用它。

更新

再次閱讀您的問題后,我意識到您的最終目標不一定是 HMVC,而是 URI 操作。 如果我錯了,請糾正我,但似乎您正在嘗試使用第一部分作為方法名稱並完全省略控制器名稱來完成 URL。

如果是這種情況,您可以通過對路線發揮創意來獲得更簡潔的解決方案。

對於一個非常基本的示例,假設您有兩個控制器, controller1controller2 Controller1有一個方法method_1 -並且controller2有一個方法method_2

您可以像這樣設置路由:

$route['method_1'] = "controller1/method_1";
$route['method_2'] = "controller2/method_2";

然后,你可以調用方法1通過URL http://site.com/method_1和方法2 http://site.com/method_2

盡管這是一個硬編碼的、非常基本的示例 - 但如果您需要做的只是從 URL 中刪除控制器,它可以讓您到達您需要的位置。


您還可以重新映射您的控制器

來自文檔:“如果您的控制器包含一個名為 _remap() 的函數,無論您的 URI 包含什么,它都會被調用。”:

public function _remap($method)
{
    if ($method == 'some_method')
    {
        $this->$method();
    }
    else
    {
        $this->default_method();
    }
}

您不能直接從另一個控制器調用控制器方法

我的解決方案是使用繼承並從庫控制器擴展您的控制器

class Controller1 extends CI_Controller {

    public function index() {
        // some codes here
    }

    public function methodA(){
        // code here
    }
}

在您的控制器中,我們稱之為Mycontoller它將擴展Controller1

include_once (dirname(__FILE__) . "/controller1.php");

class Mycontroller extends Controller1 {

    public function __construct() {
        parent::__construct();
    }

    public function methodB(){
        // codes....
    }
}

你可以從 mycontroller 調用 methodA

http://example.com/mycontroller/methodA

http://example.com/mycontroller/methodB

這個解決方案對我有用

我有一個類似的問題。 我想要兩個控制器:

homepage.php - 面向公眾的主頁

home.php - 用戶登錄后的主屏幕

我希望他們都從“mydomain.com”中讀取

我能夠通過在我的路由配置中將 'hompepage' 設置為默認控制器並向 homepage.php 添加一個重映射功能來實現這一點

function _remap()
{
  if(user_is_logged_in())
  {
    require_once(APPPATH.'controllers/home.php'); 
    $oHome =  new Home();
    $oHome->index();
  }
  else
  {
    $this->index();
  }
}

我在嘗試各種方法時遇到找不到會話文件的錯誤,最終實現了這樣。 將該函數設為靜態(我想在另一個控制器中調用它),並像這樣調用

require_once('Welcome.php');
Welcome::hello();

雖然上述方法可能有效,但這里有一個非常好的方法。

使用 MY 控制器擴展核心控制器,然后為所有其他控制器擴展此 MY 控制器。 例如,你可以有:

class MY_Controller extends CI_Controller {
    public function is_logged()
    {
        //Your code here
    }
public function logout()
    {
        //Your code here
    }
}

然后您的其他控制器可以按如下方式擴展它:

class Another_Controller extends MY_Controller {
    public function show_home()
    {
         if (!$this->is_logged()) {
           return false;
         }
    }
public function logout()
    {
        $this->logout();
    }
}

您可以通過多種方式將一個控制器訪問到另一個控制器。

class Test1 extends CI_controller
{
    function testfunction(){
        return 1;
    }
}

然后創建另一個類,並在其中包含第一個類,並用您的類擴展它。

include 'Test1.php';

class Test extends Test1
{
    function myfunction(){
        $this->test();
        echo 1;
    }
}

我來這里是因為我需要在 Twig 中創建一個{{ render() }}函數,以模擬 Symfony2 的行為。 從視圖渲染控制器非常酷,可以顯示獨立的小部件或 ajax 可重新加載的東西。

即使你不是 Twig 用戶,你仍然可以使用這個助手並在你的視圖中使用它來渲染控制器,使用<?php echo twig_render('welcome/index', $param1, $param2, $_); ?> <?php echo twig_render('welcome/index', $param1, $param2, $_); ?> . 這將回顯您的控制器輸出的所有內容。

這里是:

助手/twig_helper.php

<?php

if (!function_exists('twig_render'))
{

    function twig_render()
    {
        $args = func_get_args();
        $route = array_shift($args);
        $controller = APPPATH . 'controllers/' . substr($route, 0, strrpos($route, '/'));

        $explode = explode('/', $route);
        if (count($explode) < 2)
        {
            show_error("twig_render: A twig route is made from format: path/to/controller/action.");
        }

        if (!is_file($controller . '.php'))
        {
            show_error("twig_render: Controller not found: {$controller}");
        }
        if (!is_readable($controller . '.php'))
        {
            show_error("twig_render: Controller not readable: {$controller}");
        }
        require_once($controller . '.php');

        $class = ucfirst(reset(array_slice($explode, count($explode) - 2, 1)));
        if (!class_exists($class))
        {
            show_error("twig_render: Controller file exists, but class not found inside: {$class}");
        }

        $object = new $class();
        if (!($object instanceof CI_Controller))
        {
            show_error("twig_render: Class {$class} is not an instance of CI_Controller");
        }

        $method = $explode[count($explode) - 1];
        if (!method_exists($object, $method))
        {
            show_error("twig_render: Controller method not found: {$method}");
        }

        if (!is_callable(array($object, $method)))
        {
            show_error("twig_render: Controller method not visible: {$method}");
        }

        call_user_func_array(array($object, $method), $args);

        $ci = &get_instance();
        return $ci->output->get_output();
    }

}

特定於 Twig 用戶(將此代碼調整為您的 Twig 實現):

圖書館/Twig.php

$this->_twig_env->addFunction('render', new Twig_Function_Function('twig_render'));

用法

{{ render('welcome/index', param1, param2, ...) }}

使用我在下面創建的代碼創建一個助手並將其命名為 controller_helper.php。

config下的autoload.php文件中自動加載您的助手。

從您的方法調用controller('name')加載控制器。

請注意, name是控制器的文件名。

此方法會將'_controller'附加到您的控制器'name' 要調用控制器中的方法,只需運行$this->name_controller->method(); 如上所述加載控制器后。

<?php

if(!function_exists('controller'))
{
    function controller($name)
    {
        $filename = realpath(__dir__ . '/../controllers/'.$name.'.php');

        if(file_exists($filename))
        {
            require_once $filename;

            $class = ucfirst($name);

            if(class_exists($class))
            {
                $ci =& get_instance();

                if(!isset($ci->{$name.'_controller'}))
                {
                    $ci->{$name.'_controller'} = new $class();
                }
            }
        }
    }
}
?>

您可以從 Controller 調用 Model,因此將您的函數放在 Model 中,然后從 controller 調用它。對我有用。 (代碼點火器 3)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM