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
CodeIgniter: Load controller within controller
提问by Daniel
I have a home
controller with an index
action that displays a set of featured products. However, the products are managed through a product
controller including a proprietary model and views.
我有一个home
控制器,其index
动作显示一组特色产品。但是,产品是通过product
包含专有模型和视图的控制器进行管理的。
How do I access product
information from within the index
action in the home
controller? Instancing product
won't work as the class isn't loaded at runtime and CodeIgniter doesn't provide a way to dynamically load controllers. Putting the product
class 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 product
controller) 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.php
in your application/core directory. Add the following code to your newly created MY_Loader.php
file:
首先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.
然后在另一个控制器中加载控制器。