如何从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。
举一个非常基本的例子,假设你有两个控制器, controller1
和controller2
。 Controller1
有一个方法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(); } }