路由到 CodeIgniter 中的多个子文件夹

Posted

技术标签:

【中文标题】路由到 CodeIgniter 中的多个子文件夹【英文标题】:Route to multiple sub folders in CodeIgniter 【发布时间】:2011-07-09 22:41:34 【问题描述】:

我在我的控制器目录中设置了一个管理文件夹,在该文件夹下我有 3 个单独的子文件夹,其中包含控制器。

-- Controllers
---- Admin
------ Dashboard
-------- dashboard.php
-------- file.php
------ Members
-------- members.php
-------- file.php
------ Settings
-------- settings.php
-------- file.php

我尝试像这样在 routes.php 文件中路由它

$route['admin/(:any)/(:any)'] = 'admin/$1/$2';
$route['admin/(:any)'] = 'admin/$1/$1';
$route['admin'] = 'admin/index';

我该怎么做才能解决这个问题?

【问题讨论】:

【参考方案1】:

为了 Codeigniter 3.x 的兼容性:自从放弃对 PHP 4 的支持以来,EXT 常量的使用已被弃用。不再需要维护不同的文件扩展名,在这个新的 CodeIgniter 版本 (3.x) 中,EXT常数已被删除。改用“.php”。

所以新的MY_Router.php:

<?php

/*
 * Custom router function v 0.3
 *
 * Add functionality : read into more than one sub-folder
 * Compatible with Codeigniter 3.x
 *
 */

Class MY_Router extends CI_Router

    Function MY_Router()
    
        parent::__construct();
    

    function _validate_request($segments)
    

       if (file_exists(APPPATH.'controllers/'.$segments[0].".php"))
        
            return $segments;
        

        if (is_dir(APPPATH.'controllers/'.$segments[0]))
        
            $this->set_directory($segments[0]);
            $segments = array_slice($segments, 1);

            /* ----------- ADDED CODE ------------ */

            while(count($segments) > 0 && is_dir(APPPATH.'controllers/'.$this->directory.$segments[0]))
            
                // Set the directory and remove it from the segment array
            //$this->set_directory($this->directory . $segments[0]);
            if (substr($this->directory, -1, 1) == '/')
                $this->directory = $this->directory . $segments[0];
            else
                $this->directory = $this->directory . '/' . $segments[0];

            $segments = array_slice($segments, 1);
            

            if (substr($this->directory, -1, 1) != '/')
                $this->directory = $this->directory . '/';

            /* ----------- END ------------ */

            if (count($segments) > 0)
            

                if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().'/'.$segments[0].".php"))
                
                    show_404($this->fetch_directory().$segments[0]);
                
            
            else
            
                $this->set_class($this->default_controller);
                $this->set_method('index');

                if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().'/' .$this->default_controller.".php"))
                
                    $this->directory = '';
                    return array();
                

            

            return $segments;
        

        show_404($segments[0]);
    

【讨论】:

【参考方案2】:

我遇到了sub-directories4-5 levels 的问题(例如/controllers/folder1/folder2/folder3/folder4/my-controller),并从

while(count($segments) > 0 && 
     // checks only $this->directory having a /
     is_dir(APPPATH.'controllers/'.$this->directory.$segments[0]))

while(count($segments) > 0 && 
   // check $this->directory having a /
  (is_dir(APPPATH.'controllers/'.$this->directory.$segments[0]) ||  
      // check $this->directory not having /
      is_dir(APPPATH.'controllers/'.$this->directory.'/'.$segments[0])))

它对我有用。

上面的对于2-3 sub-directories 是可以的,但对于4-5 sub-directory 层次结构是不行的。

【讨论】:

【参考方案3】:

此代码已经在互联网上,但我对其进行了修改以使其适用于 codeigniter 2.1

在此处查看旧源: http://glennpratama.wordpress.com/2009/10/20/multi-level-subfolder-for-controller-in-codeigniter/

在application/core目录下新建文件MY_Router.php,复制如下代码:

<?php

/*
 * Custom router function v 0.2
 *
 * Add functionality : read into more than one sub-folder
 *
 */

Class MY_Router extends CI_Router

    Function MY_Router()
    
        parent::__construct();
    

    function _validate_request($segments)
    
        if (file_exists(APPPATH.'controllers/'.$segments[0].EXT))
        
            return $segments;
        

        if (is_dir(APPPATH.'controllers/'.$segments[0]))
        
            $this->set_directory($segments[0]);
            $segments = array_slice($segments, 1);

            /* ----------- ADDED CODE ------------ */

            while(count($segments) > 0 && is_dir(APPPATH.'controllers/'.$this->directory.$segments[0]))
            
                // Set the directory and remove it from the segment array
            //$this->set_directory($this->directory . $segments[0]);
            if (substr($this->directory, -1, 1) == '/')
                $this->directory = $this->directory . $segments[0];
            else
                $this->directory = $this->directory . '/' . $segments[0];

            $segments = array_slice($segments, 1);
            

            if (substr($this->directory, -1, 1) != '/')
                $this->directory = $this->directory . '/';

            /* ----------- END ------------ */

            if (count($segments) > 0)
            

                if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().'/'.$segments[0].EXT))
                
                    show_404($this->fetch_directory().$segments[0]);
                
            
            else
            
                $this->set_class($this->default_controller);
                $this->set_method('index');

                if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().'/' .$this->default_controller.EXT))
                
                    $this->directory = '';
                    return array();
                

            

            return $segments;
        

        show_404($segments[0]);
    

【讨论】:

这是 jondavidjohn 接受的答案中链接到的代码的更新变体。【参考方案4】:

“开箱即用”codeigniter 不支持控制器目录中的多个子目录级别,仅支持一个。

There is a way to extend the routing class to support this, check this blog entry.

【讨论】:

版本3还是这样吗?

以上是关于路由到 CodeIgniter 中的多个子文件夹的主要内容,如果未能解决你的问题,请参考以下文章

使用 CodeIgniter 在子文件夹中路由控制器

子文件夹中的 Codeigniter 控制器扩展到一个之外

根域上的WordPress站点工作但子文件夹中的codeigniter不起作用

在 CodeIgniter 中重新路由页面时如何防止重复内容?

CodeIgniter:从子文件夹访问视图

Codeigniter 中的路由 - 自动