CodeIgniter子目录中的默认控制器无法正常工作

时间:2011-06-30 01:16:22

标签: php codeigniter

路由配置中的default_controller设置为“home.php”。

我有一个控制器的子目录,我们称之为“文件夹”。因此,如果我访问http://mysite.com/folder/,应该调用默认控制器“folder / home.php”吗?

但由于某种原因,这不起作用,我得到了404.访问http://mysite.com/folder/homehttp://mysite.com/folder/home/index按预期工作。除此之外,默认控制器在根目录中工作(http://mysite.com加载home.php)。

任何想法,还有其他人经历过这个吗?我无法理解它 - 它似乎是一个CI问题,但我找不到其他人有同样的问题。

从我至少理解的方式来看,文档表明这应该可以正常工作:http://codeigniter.com/user_guide/general/controllers.html#subfolders

将默认控制器设置为“folder / home.php”意味着http://mysite.com/folder/可以正常工作。除了我希望默认控制器只是“home.php” - 无论是在根目录还是在子目录中,都应该加载该目录中的home.php,如文档所示。

干杯

9 个答案:

答案 0 :(得分:23)

对于controllers文件夹中的每个子文件夹,您必须在routes.php中指定默认控制器。内置的$route['default_controller']不适用于子文件夹。

例如:要将folder子文件夹的默认控制器设置为home,请将以下内容添加到/application/config/routes.php文件中:

$route['folder'] = "folder/home";

表示http://mysite.com/folder/与网址http://mysite.com/folder/home相同。

答案 1 :(得分:12)

您可以根据需要扩展系统路由器,

  1. application/core/目录
  2. 中创建My_Router.php

    / *  *要更改此许可证标题,请在“项目属性”中选择“许可证标题”。  *要更改此模板文件,请选择“工具”|模板  *并在编辑器中打开模板。  * /

    /**
     * Description of My_Router
     *
     * @author girish
     */
    class My_Router extends CI_Router {
    
        //put your code here
        public function __construct($routing = NULL) {
            parent::__construct($routing);
        }
    
        protected function _set_default_controller() {
        if (empty($this->default_controller)) {
            show_error('Unable to determine what should be displayed. A default route has not been specified in the routing file.');
        }
    
        // Is the method being specified?
        if (sscanf($this->default_controller, '%[^/]/%[^/]/%s', $directory, $class, $method) !== 3) {
            $method = 'index';
        }
        if (is_dir(APPPATH . 'controllers' . DIRECTORY_SEPARATOR . $directory) === true) {
    
            if (!file_exists(APPPATH . 'controllers' . DIRECTORY_SEPARATOR . $directory . DIRECTORY_SEPARATOR . ucfirst($class) . '.php')) {
                // This will trigger 404 later
                return;
            }
            $this->set_directory($directory);
            $this->set_class($class);
            $this->set_method($method);
        } else {
            if (sscanf($this->default_controller, '%[^/]/%s', $class, $method) !== 2) {
                $method = 'index';
            }
            if (!file_exists(APPPATH . 'controllers' . DIRECTORY_SEPARATOR . ucfirst($class) . '.php')) {
                // This will trigger 404 later
                return;
            }
            $this->set_class($class);
            $this->set_method($method);
        }
        // Assign routed segments, index starting from 1
        $this->uri->rsegments = array(
            1 => $class,
            2 => $method
        );
    
        log_message('debug', 'No URI present. Default controller set.');
       }
    
    }
    

    并从自定义方法覆盖_set_default_controller(),它将从子目录控制器以及根目录控制器工作。

    并在application/config/routes.php

    如果你需要子目录默认控制器,那么<​​/ p>

     $route['default_controller'] = "admin/admins/login";
    
    • admin - folder
    • 管理员 - 控制器
    • 登录 - 方法

    如果你需要root目录默认控制器,那么<​​/ p>

     $route['default_controller'] = "welcome/index";
    
    • welcome - controller
    • index - method

    不确定它是否适用于所有版本,但在CI3.0.6中进行了测试

答案 2 :(得分:4)

如果你想保持灵活性,你需要传递起始文件夹后的所有内容(在application/config/config.php中):

$route['home'] = "home/whatever";
$route['home/(:any)'] = "home/whatever/$1";

答案 3 :(得分:1)

默认路由用于告知CI,如果URI不包含数据,则应加载哪个控制器类。

enter image description here

$route['default_controller'] = "unicorn/best";

所以,当我加载

http://example.com/index.php/unicorn/

将加载最佳控制器。

当我加载

http://example.com/

http://example.com/index.php/horse/

将加载最佳控制器。

答案 4 :(得分:0)

我的文件夹结构

--controllers
  --backend
  --frontend
    --home.php
    --products.php
    --productDetail.php
--homeIndex.php

在config / routes.php

$route['default_controller'] = 'homeIndex';
$route['frontend'] = 'frontend/home';
$route['backend'] = 'backend/home';

在controllers / homeIndex.php

<?php    
defined('BASEPATH') OR exit('No direct script access allowed');
require_once(APPPATH.'controllers/frontend/Home.php');    
class homeIndex extends home {    
    public function index() {
        $this->action();
    }    
}

默认情况下将加载homeIndex,并从homeIndex调用前端/ home / action函数。

答案 5 :(得分:0)

将此行添加到application / config / routes.php

$this->set_directory( "yourfoldername" );
$route['default_controller'] = 'controller name';

答案 6 :(得分:0)

在application / config / routes.php中只需添加

<mat-checkbox matSuffix color="accent" class="ml-4" [disabled]="yourBoolean"></mat-checkbox>

在这里,用户是我的文件夹名称。然后,在默认控制器中,您可以调用用户文件夹中的任何控制器,然后按功能名称

答案 7 :(得分:0)

如果我使用以下代码

$this->set_directory( "user" );
$route['default_controller'] = 'home/index';

然后另一个子目录中的另一个路由不起作用。

假设我使用控制器目录中的子目录用户作为默认控制器。但是,如果我想将FrontEnd子目录用于其他路由,

$this->set_directory( "FrontEnd" );
$route['product/(:any)'] = 'product/$1';

然后它不起作用。

答案 8 :(得分:0)

即使这个问题有很多(和一个可以接受的答案),我仍然想发表我的看法。

我发现子文件夹适用于常规路线。例如,我可以这样做:

$route['frontend/test'] = "frontend/Welcome/test";

,如果我访问site/frontend/test,它会按预期工作。问题是让"default_controller"与子文件夹一起使用。例如,以下操作无效:

$route['default_controller'] = "frontend/Welcome/test";

如果我们检查URI Routing > Reserved Routes部分,它会说:

您不能将目录用作此设置的一部分!

所以我们需要破解。我使用了Girishapproach。我已经检查过system/core/Router.php并创建了application/core/MY_Router.php

起初,我认为Girish对_set_default_controller方法进行了静态更改,该方法仅允许子文件夹。我认为它应该是动态的,子文件夹应该是可选的。后来,我意识到他也为此提供了支持,但是他的代码具有重复的逻辑,我已经完成了我的工作。所以我还是要发布它。

<?php

class MY_Router extends CI_Router {
    
    /**
     * The default controller expects a string in the following format: "controller/method".
     * The method at the end is optional. If the method is omitted, the default method is "index".
     * 
     * Examples:
     *  * $route['default_controller'] = "Welcome";
     *  * $route['default_controller'] = "Welcome/index";
     * 
     * Both end up being routed to "Welcome/index".
     * 
     * The default controller does NOT expect a subfolder in the "controllers" folder. So the following won't work:
     *  * $route['default_controller'] = "frontend/Welcome/index"
     * 
     * To make subfolders work, _set_default_controller() needs to be modified, and that's what this MY_Router is for.
     *
     * The modification is kept to a minimum and is marked.
     */
    protected function _set_default_controller()
    {
        if (empty($this->default_controller))
        {
            show_error('Unable to determine what should be displayed. A default route has not been specified in the routing file.');
        }
        
        /* START MODIFICATION */
        
        /*
            Removing this block, as it only allows/look for "controller/method".
            // Is the method being specified?
            if (sscanf($this->default_controller, '%[^/]/%s', $class, $method) !== 2)
            {
                $method = 'index';
            }
        */
        
        /*
            Instead of just checking for "controller/method", we need to also look for a subfolder.
            Because the latter operations depend on the first segment.
            So, the first thing to do is to figure out if the first segment is a folder or a class/file.
            Possible inputs:
                "Welcome"                   -> class                -> autocomplete
                "Welcome/index"             -> class/method
                "frontend"                  -> folder
                "frontend/Welcome"          -> folder/class         -> autocomplete
                "frontend/Welcome/index"    -> folder/class/method
        */
        
        $segments = explode("/", $this->default_controller);
        $segments = array_filter($segments); // ignore leading and trailing slashes
        
        if (count($segments) > 3) {
            show_error('Invalid controller. Default controller supports only one subfolder.');
        }
        
        $method = null;
        
        // If the first segment is a folder, the second needs to be a class/file.
        if (is_dir(APPPATH.'controllers/'.$segments[0])) {
            $this->set_directory($segments[0]);
            if (!isset($segments[1])) {
                show_error('Invalid controller. A subfolder is provided, but the controller class/file is missing.');
            }
            $class = $segments[1];
            if (isset($segments[2])) {
                $method = $segments[2];
            }
        }
        // If the first segment is NOT a folder, then it's a class/file.
        else {
            $class = $segments[0];
            if (isset($segments[1])) {
                $method = $segments[1];
            }
        }
        
        // If the method isn't specified, assume that it's "index".
        if (!$method) {
            $method = "index";
        }
        
        /* END MODIFICATION */
        
        if ( ! file_exists(APPPATH.'controllers/'.$this->directory.ucfirst($class).'.php'))
        {
            // This will trigger 404 later
            return;
        }
        
        $this->set_class($class);
        $this->set_method($method);
        
        // Assign routed segments, index starting from 1
        $this->uri->rsegments = array(
            1 => $class,
            2 => $method
        );
        
        log_message('debug', 'No URI present. Default controller set.');
    }
    
}