php CodeIgniter:在控制器内加载控制器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6091100/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 23:19:51  来源:igfitidea点击:

CodeIgniter: Load controller within controller

phpcodeigniter

提问by Daniel

I have a homecontroller with an indexaction that displays a set of featured products. However, the products are managed through a productcontroller including a proprietary model and views.

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

How do I access productinformation from within the indexaction in the homecontroller? Instancing productwon't work as the class isn't loaded at runtime and CodeIgniter doesn't provide a way to dynamically load controllers. Putting the productclass into a library file doesn't really work, either.

如何product从控制器的index操作中访问信息home?实例化product将不起作用,因为该类未在运行时加载,并且 CodeIgniter 不提供动态加载控制器的方法。将product类放入库文件也不起作用。

To be precise, I need the product views (filled with data processed by the productcontroller) inserted in the index view. I'm running CodeIgniter 2.0.2.

准确地说,我需要product在索引视图中插入产品视图(填充由控制器处理的数据)。我正在运行 CodeIgniter 2.0.2。

采纳答案by Wesley Murch

If you're interested, there's a well-established package out there that you can add to your Codeigniter project that will handle this:

如果您有兴趣,这里有一个完善的包,您可以将其添加到您的 Codeigniter 项目中来处理此问题:

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

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

Modular Extensionsmakes the CodeIgniter PHP framework modular. Modules are groups of independent components, typically model, controller and view, arranged in an application modules sub-directory, that can be dropped into other CodeIgniter applications.

模块化扩展使 CodeIgniter PHP 框架模块化。模块是一组独立的组件,通常是模型、控制器和视图,排列在应用程序模块子目录中,可以放入其他 CodeIgniter 应用程序中。

OK, so the big change is that now you'd be using a modular structure - but to me this is desirable. I have used CI for about 3 years now, and can't imagine life without Modular Extensions.

好的,所以最大的变化是现在您将使用模块化结构 - 但对我来说这是可取的。我已经使用 CI 大约 3 年了,无法想象没有模块化扩展的生活。

Now, here's the part that deals with directly calling controllers for rendering view partials:

现在,这是处理直接调用控制器以呈现视图部分的部分:

// 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); ?>

That's all there is to it. I typically use this for loading little "widgets" like:

这里的所有都是它的。我通常使用它来加载小“小部件”,例如:

  • Event calendars
  • List of latest news articles
  • Newsletter signup forms
  • Polls
  • 活动日历
  • 最新新闻文章列表
  • 通讯报名表
  • 民意调查

Typically I build a "widget" controller for each module and use it only for this purpose.

通常,我为每个模块构建一个“小部件”控制器,并且仅将其用于此目的。

Your question was also one of my first questions when I started with Codeigniter. I hope this helps you out, even though it may be a bit more than you were looking for. I've been using MX ever since and haven't looked back.

当我开始使用 Codeigniter 时,您的问题也是我的第一个问题。我希望这对您有所帮助,即使它可能比您想要的要多一些。从那以后我就一直在使用 MX 并且没有回头。

Make sure to read the docs and check out the multitude of information regarding this package on the Codeigniter forums. Enjoy!

请务必阅读文档并在 Codeigniter 论坛上查看有关此软件包的大量信息。享受!

回答by Zulqurnain abbas

Load it like this

像这样加载

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

and call the following method:

并调用以下方法:

$this->instructor->functioname()

This works for CodeIgniter 2.x.

这适用于 CodeIgniter 2.x

回答by Joaquin Astelarra

In this cases you can try some old school php.

在这种情况下,您可以尝试使用一些老式的 php。

// insert at the beggining of home.php controller require_once(dirname(__FILE__)."/product.php"); // the controller route.

// insert at the beggining of home.php controller require_once(dirname(__FILE__)."/product.php"); // the controller route.

Then, you'll have something like:

然后,你会得到类似的东西:

Class Home extends CI_Controller
{
 public function __construct()
 {
  parent::__construct();
  $this->product = new Product();
  ...
 }

 ...
 // usage example
 public function addProduct($data)
 {
  $this->product->add($data);
 }
}

And then just use the controller's methods as you like.

然后根据需要使用控制器的方法。

回答by Salvador P.

Just to add more information to what Zain Abbas said:

只是为 Zain Abbas 所说的内容添加更多信息:

Load the controller that way, and use it like he said:

以这种方式加载控制器,并像他说的那样使用它:

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

$this->instructor->functioname();

Or you can create an object and use it this way:

或者您可以创建一个对象并以这种方式使用它:

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

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

$obj->your_function();

Hope this can help.

希望这能有所帮助。

回答by machineaddict

Based on @Joaquin Astelarra response, I have managed to write this little helper named load_controller_helper.php:

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

You can use/call it like this:

您可以像这样使用/调用它:

$this->load->helper('load_controller');
load_controller('homepage', 'not_found');

Note:The second argument is not mandatory, as it will run the method named index, like CodeIgniter would.

注意:第二个参数不是强制性的,因为它将运行名为index的方法,就像 CodeIgniter 一样。

Now you will be able to load a controller inside another controller without using HMVC.

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

Later Edit: Be aware that this method might have unexpected results. Always test it!

稍后编辑:请注意,此方法可能会产生意外结果。总是测试它!

回答by user1881928

With the following code you can load the controller classes and execute the methods.

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

This code was written for codeigniter 2.1

此代码是为 codeigniter 2.1 编写的

First add a new file MY_Loader.phpin your application/core directory. Add the following code to your newly created MY_Loader.phpfile:

首先MY_Loader.php在 application/core 目录中添加一个新文件。将以下代码添加到新创建的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);
    }

}

Now you can load all the controllers in your application/controllers directory. for example:

现在您可以加载 application/controllers 目录中的所有控制器。例如:

load the controller class Invoice and execute the function test()

加载控制器类 Invoice 并执行函数 test()

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

$this->invoice_controller->test();

or when the class is within a dir

或者当班级在目录中时

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

$this->invoice_controller->test();

It just works the same like loading a model

它就像加载模型一样工作

回答by charliefortune

There are plenty of good answers given here for loading controllers within controllers, but for me, this contradicts the mvc pattern.

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

The sentence that worries me is;

让我担心的句子是;

(filled with data processed by the product controller)

(填充了产品控制者处理的数据)

The models are there for processing and returning data. If you put this logic into your product model then you can call it from any controller you like without having to try to pervert the framework.

模型用于处理和返回数据。如果您将此逻辑放入您的产品模型中,那么您可以从您喜欢的任何控制器调用它,而无需尝试破坏框架。

Once of the most helpful quotes I read was that the controller was like the 'traffic cop', there to route requests and responses between models and views.

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

回答by Ukuser32

I know this is old, but should anyone find it more recently, I would suggest creating a separate class file in the controllers folder. Pass in the existing controller object into the class constructor and then you can access the functions from anywhere and it doesn't conflict with CI's setup and handling.

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

回答by Arkadij

Just use

只需使用

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

………………

self::index();

self::index();

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

………………

回答by Webby

According to this blog post you can load controller within another controller in codeigniter.

根据这篇博客文章,您可以在 codeigniter 中的另一个控制器中加载控制器。

http://www.techsirius.com/2013/01/load-controller-within-another.html

http://www.techsirius.com/2013/01/load-controller-within-another.html

First of all you need to extend CI_Loader

首先你需要扩展 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);
        }
    }
}

then load controller within another controller.

然后在另一个控制器中加载控制器。