如何从codeigniter中的另一个控制器加载控制器?

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

我试过使用模块,但我仍然不得不把控制器中的url

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

我有默认的控制器,所以我可以加载http://example.com/function所以我怎么可以从主函数访问控制器,所以我不必把控制器在URL中。

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

您无法从CI中的控制器加载控制器,除非您使用HMVC或其他东西。

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

UPDATE

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

如果是这种情况,您可以通过创build自己的路线来获得更清晰的解决scheme。

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

你可以像这样设置路线:

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

然后,您可以使用像http://site.com/method_1这样的URL和使用http://site.com/method_2方法2来调用方法1。

虽然这是一个硬编码,非常基本的例子 – 但是如果你只需要从URL中删除控制器,它可以让你到达你需要的地方。


你也可以去重新映射你的控制器 。

从文档:“如果你的控制器包含一个名为_remap()的函数,无论你的URI包含什么,它总是会被调用。”:

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

是的,你可以(版本2)

在你的控制器里面这样加载

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

并调用以下方法:

 $this->whathever->functioname(); 

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

我的解决scheme是使用inheritance,并从库控制器扩展您的控制器

 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

这个解决scheme为我工作

我有一个类似的问题。 我想有两个控制器:

homepage.php – 面向公众的主页

home.php – 用户login后的主屏幕

我希望他们都从“mydomain.com”

我能够通过在我的路由configuration中将“hompepage”设置为默认控制器并将重映射function添加到homepage.php

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

我来到这里是因为我需要在Twig中创build一个{{ 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, ...) }} 

使用我在下面创build的代码创build一个帮助器,并将其命名为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(); } } } } } ?> 

我在试用各种方式的时候发现会话文件没有find错误,终于这样做了。 使function作为静态(我想调用另一个控制器),并调用像

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