38

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

我尝试使用模块,但我仍然必须将控制器放在 url 中,比如

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

我有默认控制器,所以我可以加载http://example.com/function那么我如何从 main 的函数访问控制器,这样我就不必将控制器放在 url 中。

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

4

9 回答 9

50

是的,你可以(对于第 2 版)

在控制器中像这样加载

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

并调用以下方法:

$this->whathever->functioname();
于 2014-03-13T15:08:47.397 回答
24

您不能从 CI 中的控制器加载控制器 - 除非您使用 HMVC 或其他东西。

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

更新

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

如果是这种情况,您可以通过对路线进行创意来获得更清洁的解决方案。

对于一个非常基本的示例,假设您有两个控制器,controller1并且controller2. Controller1有一个方法method_1- 并且controller2有一个方法method_2

您可以像这样设置路线:

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

然后,您可以使用类似的 URL 调用方法 1,http://site.com/method_1使用http://site.com/method_2.

尽管这是一个硬编码的、非常基本的示例 - 但如果您需要做的只是从 URL 中删除控制器,它可以让您到达您需要的位置。


您也可以重新映射您的控制器

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

public function _remap($method)
{
    if ($method == 'some_method')
    {
        $this->$method();
    }
    else
    {
        $this->default_method();
    }
}
于 2013-01-04T22:32:26.340 回答
18

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

我的解决方案是使用继承并从库控制器扩展您的控制器

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

这个解决方案对我有用

于 2013-01-05T05:30:27.143 回答
9

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

homepage.php - 面向公众的主页

home.php - 用户登录后的主屏幕

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

我可以通过在我的路由配置中将“hompepage”设置为默认控制器并向 homepage.php 添加一个重映射函数来实现这一点

function _remap()
{
  if(user_is_logged_in())
  {
    require_once(APPPATH.'controllers/home.php'); 
    $oHome =  new Home();
    $oHome->index();
  }
  else
  {
    $this->index();
  }
}
于 2013-11-24T15:37:27.703 回答
1

我在尝试各种方法时遇到会话文件未找到错误,最终实现了这样。将函数设为静态(我想在另一个控制器中调用),并调用如下

require_once('Welcome.php');
Welcome::hello();
于 2017-02-03T06:07:43.377 回答
1

虽然上述方法可能有效,但这是一个非常好的方法。

使用 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();
    }
}
于 2017-10-04T08:59:07.697 回答
1

您可以通过多种方式将一个控制器访问到另一个控制器。

class Test1 extends CI_controller
{
    function testfunction(){
        return 1;
    }
}

然后创建另一个类,并在其中包含第一个类,并用您的类扩展它。

include 'Test1.php';

class Test extends Test1
{
    function myfunction(){
        $this->test();
        echo 1;
    }
}
于 2020-01-10T05:18:08.567 回答
0

我来到这里是因为我需要{{ render() }}在 Twig 中创建一个函数来模拟 Symfony2 的行为。从视图中渲染控制器对于显示独立的小部件或 ajax 可重新加载的东西来说真的很酷。

即使你不是 Twig 用户,你仍然可以使用这个助手并在视图中使用它来渲染控制器,使用<?php echo twig_render('welcome/index', $param1, $param2, $_); ?>. 这将回显您的控制器输出的所有内容。

这里是:

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

}

特定于 Twig 用户(将此代码调整到您的 Twig 实现):

libraries/Twig.php

$this->_twig_env->addFunction('render', new Twig_Function_Function('twig_render'));

Usage

{{ render('welcome/index', param1, param2, ...) }}
于 2014-04-17T17:19:08.057 回答
0

使用我在下面创建的代码创建一个助手并将其命名为 controller_helper.php。

将您的助手自动加载autoload.phpconfig.

从您的方法调用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();
                }
            }
        }
    }
}
?>
于 2016-11-30T02:51:27.160 回答