两个或多个具有相同名称“admin”的已加载控制器在CodeIgniter中的HMVC中不起作用

时间:2013-04-11 17:16:10

标签: codeigniter

结构如下:

modules
    admin
        controllers/
            admin.php
        models/
            admin_model.php
        views/
            admin/
                index.php
    categories/
        controllers/
            admin.php
            categories.php
        models/
            categories_model.php
        views/
            admin/
                index.php
                menu.php
            frontpage.php
    posts/
        controllers/
            admin.php
            posts.php
        models/
            posts_model.php
        views/
            admin/
                index.php
                menu.php
            frontpage.php    

管理控制器如下所示:

class Admin extends Backend_Controller {

    function __construct()
    {
         parent::__construct();
         $this->load->model('categories_model');
    }

    public function index()
    {
             // index stuff
    }

    public function _menu()
    {
         $this->load->view('categories/admin/menu');
    }

}

当我从另一个模块视图中调用它时:

<?php echo Modules::run('categories/admin/_menu'); ?>

它不起作用;(

然而这有效:

<?php echo Modules::run('categories/categories'); ?>

所以我的问题是如何使用名称 admin 加载控制器,而不是名称作为模块的名称和方法“菜单

任何想法如何让它在CodeIgniter中运行?

修改

我发现如果我将控制器名称从“admin”更改为其他内容,例如“blablacontroller”它神奇地开始工作。

我已经有另一个名为“admin”的模块,所以这可能是个问题吗?

2 个答案:

答案 0 :(得分:3)

在PHP中,您只能使用名称声明一个类。例如。除非类位于不同的命名空间中,否则只能有一个Admin类。可能发生的事情是:

admin/controllers/admin.php被声明然后在脚本执行中categories/controllers/admin.php被尝试声明并在admin/controllers/admin.php已经存在时抛出错误,如果Admin类应该使用它某些代码说new Admin()

如果需要这两个类,则需要重命名一个类,或者需要重构的代码,以便在一个执行周期中只声明其中一个。我不太确定你的使用的HMVC内容是否允许命名空间,但是你可以考虑以这种方式扩展它。如果没有,可能会将两个管理类重命名为更具体的内容。

答案 1 :(得分:3)

如果我是对的,您使用的是Modular Extensions - HMVC。所以我的答案基于以下脚本:https://bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc/src/868e97533562e910d8263af22750985d57004baa/third_party/MX/Modules.php?at=default

只有在使用PHP 5.3或更高版本时才能使用。

  • 通过在类键工作之前添加 命名空间管理; ,在namepsace(admin,categories,post)中声明每个Admin类。
  • 创建* third_party / MX / Modules.php *的子类,并扩展run和load方法。如果无法扩展,则必须替换方法:/
  • 这不是全部,但那些简单的字符串操作应该在现有逻辑之前的load方法中。
  • 应使用以下语法运行模块: * Modules :: run('categories \ admin / _menu'); *

    $module = 'categories\admin';
    if (strpos($module, '\\') !== false)
    {
        // Extract namespace
        $ns = explode('\\', $module);
    
        // Get the top level namespace to locate the controller
        $top_level_ns = reset($ns); //
    
        // Remove namespace from module
        $module = array_pop($ns);
    
        // Class location
        $path = APPPATH . $top_level_ns . '/controllers/' . $module;
    
        // It's better to extend the load_file method
        include_once $path . EXT;
    
        // Full class name with namespace, we use explode on $module in case of sub folders
        $controller = '\\' . implode('\\', $ns) . '\\' . ucfirst(end(explode('/', $module))) . CI::$APP->config->item('controller_suffix');
    
        // create and register the new controller
        $alias = strtolower($controller);
        self::$registry[$alias] = new $controller($params);
    
        var_dump('Full class name: ' . $controller, 'Class path: ' . $path);
    }