php 如何从codeigniter中的另一个控制器加载控制器?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14165895/
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
How to load a controller from another controller in codeigniter?
提问by Luis Liz
I want to load a controller from a function in another controller because the library I integrated to my project I don't want to load it to the controller because I want to keep it clean and related.
我想从另一个控制器中的函数加载控制器,因为我集成到我的项目中的库我不想将它加载到控制器,因为我想保持它的清洁和相关性。
I tried using modules but I still had to put controller in the url like
我尝试使用模块,但我仍然必须将控制器放在 url 中,例如
http://example.com/maincontroller/function
http://example.com/othercontroller/function
http://example.com/maincontroller/function
http://example.com/othercontroller/function
I have default controller so I can load http://example.com/functionso how could I access the controller from a function from main so I don't have to put the controller in the url.
我有默认控制器,所以我可以加载http://example.com/function,所以我怎么能从 main 的函数访问控制器,所以我不必把控制器放在 url 中。
I'm still willing to use HMVC if I can load the controller function from the main controller function.
如果我可以从主控制器功能加载控制器功能,我仍然愿意使用 HMVC。
采纳答案by swatkins
You can't load a controller from a controller in CI - unless you use HMVC or something.
你不能从 CI 中的控制器加载控制器 - 除非你使用 HMVC 或其他东西。
You should think about your architecture a bit. If you need to call a controller method from another controller, then you should probably abstract that code out to a helper or library and call it from both controllers.
您应该稍微考虑一下您的架构。如果您需要从另一个控制器调用控制器方法,那么您可能应该将该代码抽象为帮助程序或库,并从两个控制器调用它。
UPDATE
更新
After reading your question again, I realize that your end goal is not necessarily HMVC, but URI manipulation. Correct me if I'm wrong, but it seems like you're trying to accomplish URLs with the first section being the method name and leave out the controller name altogether.
再次阅读您的问题后,我意识到您的最终目标不一定是 HMVC,而是 URI 操作。如果我错了,请纠正我,但似乎您正在尝试使用第一部分作为方法名称并完全省略控制器名称来完成 URL。
If this is the case, you'd get a cleaner solution by getting creative with your routes.
如果是这种情况,您将通过对路线发挥创意来获得更简洁的解决方案。
For a really basic example, say you have two controllers, controller1and controller2. Controller1has a method method_1- and controller2has a method method_2.
对于一个非常基本的示例,假设您有两个控制器,controller1并且controller2. Controller1有方法method_1——controller2有方法method_2。
You can set up routes like this:
您可以像这样设置路由:
$route['method_1'] = "controller1/method_1";
$route['method_2'] = "controller2/method_2";
Then, you can call method 1 with a URL like http://site.com/method_1and method 2 with http://site.com/method_2.
然后,您可以使用类似 URL 调用方法 1,http://site.com/method_1使用http://site.com/method_2.
Albeit, this is a hard-coded, very basic, example - but it could get you to where you need to be if all you need to do is remove the controller from the URL.
尽管这是一个硬编码的、非常基本的示例 - 但如果您需要做的只是从 URL 中删除控制器,它可以让您到达您需要的位置。
You could also go with remapping your controllers.
您还可以重新映射您的控制器。
From the docs: "If your controller contains a function named _remap(), it will always get called regardless of what your URI contains.":
来自文档:“如果您的控制器包含一个名为 _remap() 的函数,无论您的 URI 包含什么,它都会被调用。”:
public function _remap($method)
{
if ($method == 'some_method')
{
$this->$method();
}
else
{
$this->default_method();
}
}
回答by Geomorillo
yes you can (for version 2)
是的,你可以(对于版本 2)
load like this inside your controller
在您的控制器中像这样加载
$this->load->library('../controllers/whathever');
and call the following method:
并调用以下方法:
$this->whathever->functioname();
回答by Nerdroid
you cannot call a controller method from another controller directly
您不能直接从另一个控制器调用控制器方法
my solution is to use inheritances and extend your controller from the library controller
我的解决方案是使用继承并从库控制器扩展您的控制器
class Controller1 extends CI_Controller {
public function index() {
// some codes here
}
public function methodA(){
// code here
}
}
in your controller we call it Mycontollerit will extends Controller1
在您的控制器中,我们称之为它将Mycontoller扩展Controller1
include_once (dirname(__FILE__) . "/controller1.php");
class Mycontroller extends Controller1 {
public function __construct() {
parent::__construct();
}
public function methodB(){
// codes....
}
}
and you can call methodA from mycontroller
你可以从 mycontroller 调用 methodA
http://example.com/mycontroller/methodA
http://example.com/mycontroller/methodA
http://example.com/mycontroller/methodB
http://example.com/mycontroller/methodB
this solution worked for me
这个解决方案对我有用
回答by Keith Ritter
I had a similar problem. I wanted to have two controllers:
我有一个类似的问题。我想要两个控制器:
homepage.php - public facing homepage
homepage.php - 面向公众的主页
home.php - home screen once a user was logged in
home.php - 用户登录后的主屏幕
and I wanted them both to read from 'mydomain.com'
我希望他们都从“mydomain.com”中读取
I was able to accomplish this by setting 'hompepage' as the default controller in my routes config and adding a remap function to homepage.php
我能够通过在我的路由配置中将 'hompepage' 设置为默认控制器并向 homepage.php 添加一个重映射功能来实现这一点
function _remap()
{
if(user_is_logged_in())
{
require_once(APPPATH.'controllers/home.php');
$oHome = new Home();
$oHome->index();
}
else
{
$this->index();
}
}
回答by Smith
While the methods above might work, here is a very good method.
虽然上述方法可能有效,但这里有一个非常好的方法。
Extend the core controller with a MY controller, then extend this MY controller for all your other controllers. For example, you could have:
使用 MY 控制器扩展核心控制器,然后为所有其他控制器扩展此 MY 控制器。例如,你可以有:
class MY_Controller extends CI_Controller {
public function is_logged()
{
//Your code here
}
public function logout()
{
//Your code here
}
}
Then your other controllers could then extend this as follows:
然后您的其他控制器可以按如下方式扩展它:
class Another_Controller extends MY_Controller {
public function show_home()
{
if (!$this->is_logged()) {
return false;
}
}
public function logout()
{
$this->logout();
}
}
回答by Shehroz Altaf
There are many ways by which you can access one controller into another.
您可以通过多种方式将一个控制器访问到另一个控制器。
class Test1 extends CI_controller
{
function testfunction(){
return 1;
}
}
Then create another class, and include first Class in it, and extend it with your class.
然后创建另一个类,并在其中包含第一个类,并用您的类扩展它。
include 'Test1.php';
class Test extends Test1
{
function myfunction(){
$this->test();
echo 1;
}
}
回答by Alain Tiemblo
I came here because I needed to create a {{ render() }}function in Twig, to simulate Symfony2's behaviour. Rendering controllers from view is really cool to display independant widgets or ajax-reloadable stuffs.
我来到这里是因为我需要{{ render() }}在 Twig 中创建一个函数来模拟 Symfony2 的行为。从视图渲染控制器非常酷,可以显示独立的小部件或 ajax 可重新加载的东西。
Even if you're not a Twig user, you can still take this helper and use it as you want in your views to render a controller, using <?php echo twig_render('welcome/index', $param1, $param2, $_); ?>. This will echo everything your controller outputted.
即使您不是 Twig 用户,您仍然可以使用此帮助程序并根据需要在视图中使用它来呈现控制器,使用<?php echo twig_render('welcome/index', $param1, $param2, $_); ?>. 这将回显您的控制器输出的所有内容。
Here it is:
这里是:
helpers/twig_helper.php
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();
}
}
Specific for Twig users (adapt this code to your Twig implementation):
特定于 Twig 用户(将此代码调整为您的 Twig 实现):
libraries/Twig.php
libraries/Twig.php
$this->_twig_env->addFunction('render', new Twig_Function_Function('twig_render'));
Usage
Usage
{{ render('welcome/index', param1, param2, ...) }}
回答by Taurai Muzopa
Create a helper using the code I created belows and name it controller_helper.php.
使用我在下面创建的代码创建一个助手并将其命名为 controller_helper.php。
Autoload your helper in the autoload.phpfile under config.
自动加载你的助手在中autoload.php下文件config。
From your method call controller('name')to load the controller.
从您的方法调用controller('name')加载控制器。
Note that nameis the filename of the controller.
请注意,这name是控制器的文件名。
This method will append '_controller'to your controller 'name'. To call a method in the controller just run $this->name_controller->method();after you load the controller as described above.
此方法将附加'_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();
}
}
}
}
}
?>
回答by Rajesh
I was having session file not found error while tried various ways, finally achieved like this. Made the function as static (which I want to call in the another controller), and called like
我在尝试各种方法时遇到找不到会话文件的错误,最终实现了这样。将该函数设为静态(我想在另一个控制器中调用它),并像这样调用
require_once('Welcome.php');
Welcome::hello();

