【问题标题】:How to load a controller from another controller in codeigniter?如何在codeigniter中从另一个控制器加载控制器?
【发布时间】:2012-12-19 09:47:52
【问题描述】:

我想从另一个控制器中的函数加载控制器,因为我集成到我的项目中的库我不想将它加载到控制器,因为我想保持它干净和相关。

我尝试使用模块,但我仍然必须将控制器放在 url 中,例如

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

我有默认控制器,所以我可以加载http://example.com/function,那么我如何从 main 函数访问控制器,这样我就不必将控制器放在 url 中。

如果我可以从主控制器功能加载控制器功能,我仍然愿意使用 HMVC。

【问题讨论】:

  • Codeigniter(以及一般的 MVC)并非旨在以这种方式工作。控制器不调用其他控制器。如果您发现自己需要这样做,这可能表明您的应用架构需要重构。

标签: php codeigniter hmvc


【解决方案1】:

是的,你可以(对于第 2 版)

在你的控制器中像这样加载

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

并调用以下方法:

$this->whathever->functioname();

【讨论】:

  • 这种工作,但如果你尝试加载 2 个控制器,那么由于 $CI 对象,事情开始变得不稳定。
  • @Matt 您能否简要说明一下为什么这不合适?谢谢!
  • 它给出了错误信息。 _ 在第 196 行的 C:\xampp\htdocs\garments\system\core\Common.php 中找不到类“CI_Template”_
  • 这两个控制器都是用会话库构建的。实施您的解决方案后,它无法加载会话。 “找不到指定的类:Session.php”
  • @SaggyManateeAndSwanFolk 我遇到了同样的问题。我敢打赌,这个答案适用于 CodeIgniter 2,但不一定适用于 CodeIgniter 3。
【解决方案2】:

您不能从 CI 中的控制器加载控制器 - 除非您使用 HMVC 或其他东西。

您应该考虑一下您的架构。如果您需要从另一个控制器调用控制器方法,那么您可能应该将该代码抽象到帮助程序或库中,并从两个控制器中调用它。

更新

再次阅读您的问题后,我意识到您的最终目标不一定是 HMVC,而是 URI 操作。如果我错了,请纠正我,但您似乎正在尝试完成 URL,第一部分是方法名称,而完全省略了控制器名称。

如果是这种情况,您可以通过获取creative with your routes 获得更简洁的解决方案。

举一个非常基本的例子,假设您有两个控制器,controller1controller2Controller1 有一个方法 method_1 - 并且controller2 有一个方法 method_2

你可以这样设置路线:

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

然后,您可以使用http://site.com/method_1 之类的URL 调用方法1,使用http://site.com/method_2 调用方法2。

尽管这是一个硬编码的、非常基本的示例 - 但如果您需要做的只是从 URL 中删除控制器,它可以让您到达您需要的位置。


你也可以选择remapping your controllers

来自文档:“如果您的控制器包含名为 _remap() 的函数,则无论您的 URI 包含什么,它都会被调用。”:

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

【讨论】:

  • 是的,我知道我不能从另一个控制器调用,但是使用 hmvc 我需要使用链接中的控制器,如上所述,因为我想保持它干净。另外,另一个控制器不是我的,它来自另一个库。你们认为将其更改为库还是 hmvc 更好?
  • HMVC 很好,并且有助于构建一些东西。这取决于此用例可能影响您的频率。如果只是几次,你需要这个,那么我会说图书馆是最好的。但是,如果这是您可能经常处理的事情,那么请继续添加额外的位以使用 HMVC。但是,在再次阅读您的问题后,我已通过对 URL 问题的回复更新了我的答案。
  • 什么人使用 HMVC?
  • @jayarjo HMVC 是一种架构模式——基本上,它是一种在应用程序中拥有自包含的 mvc 结构模块的方法。其他一些人已经在 CodeIgniter 中解决了如何做到这一点:herehere
【解决方案3】:

你不能直接从另一个控制器调用一个控制器方法

我的解决方案是使用继承并从库控制器扩展您的控制器

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

这个解决方案对我有用

【讨论】:

  • 这是一个很好的选择。谢谢分享。但是我使用了另一种方法以旧方式将控制器加载到另一个控制器中。在我使用这个http://stackoverflow.com/a/16354422/1057527之前我没有看到你的答案
  • 使用这种方式,它每次都会包含文件 controller1.php,即使在那些不需要它的函数中也是如此。我认为最好将文件包含在特定函数中而不是所有函数中。
  • @DeepKakkar 你能否就你的建议提供更多帮助
【解决方案4】:

我遇到了类似的问题。我想要两个控制器:

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

【讨论】:

  • 不建议这样做,但可以作为一种情况,否则实现 HMVC 或使用库
【解决方案5】:

我尝试了各种方法时出现会话文件未找到错误,最终实现了这样。将函数设为静态(我想在另一个控制器中调用),然后调用

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

【讨论】:

    【解决方案6】:

    虽然上述方法可能有效,但这是一个非常好的方法。

    使用 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();
        }
    }
    

    【讨论】:

      【解决方案7】:

      您可以通过多种方式将一个控制器访问到另一个控制器。

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

      然后创建另一个类,并在其中包含第一个 Class,并使用您的类扩展它。

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

      【讨论】:

        【解决方案8】:

        我来到这里是因为我需要在 Twig 中创建一个{{ render() }} 函数来模拟 Symfony2 的行为。从视图中渲染控制器对于显示独立的小部件或 ajax 可重新加载的东西真的很酷。

        即使您不是 Twig 用户,您仍然可以使用此帮助器并在视图中使用它来渲染控制器,使用 <?php echo twig_render('welcome/index', $param1, $param2, $_); ?>。这将回显您的控制器输出的所有内容。

        这里是:

        helpers/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, ...) }}
        

        【讨论】:

          【解决方案9】:

          使用我在下面创建的代码创建一个助手并将其命名为 controller_helper.php。

          config 下的autoload.php 文件中自动加载您的助手。

          从您的方法调用controller('name') 加载控制器。

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

          此方法会将'_controller' 附加到您的控制器'name'。要调用控制器中的方法,只需在如上所述加载控制器后运行 $this-&gt;name_controller-&gt;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();
                          }
                      }
                  }
              }
          }
          ?>
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-01-01
            • 1970-01-01
            • 2011-08-30
            • 2013-07-02
            • 1970-01-01
            • 1970-01-01
            • 2012-09-30
            • 2014-04-13
            相关资源
            最近更新 更多